Commit bbeb09b6 authored by Terry Ellison's avatar Terry Ellison Committed by Marcel Stör
Browse files

Squashed updates do get Lua51 and Lua53 working (#3075)

-  Lots of minor but nasty bugfixes to get all tests to run clean
-  core lua and test suite fixes to allow luac -F to run cleanly against test suite
-  next tranch to get LFS working
-  luac.cross -a options plus fixes from feedback
-  UART fixes and lua.c merge
-  commit of wip prior to rebaselining against current dev
-  more tweaks
parent 99aba344
/* Read-only tables for Lua */
#ifndef lrotable_h
#define lrotable_h
#include "lua.h"
#include "luaconf.h"
#include "lobject.h"
#include "llimits.h"
#include "lrotable.h"
/* Macros one can use to define rotable entries */
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_LUDATA(v) {{.p = v}, LUA_TLIGHTUSERDATA}
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#ifdef LUA_CROSS_COMPILER
#define LRO_STRKEY(k) k
#else
#define LRO_STRKEY(k) ((STORE_ATTR char *) k)
#endif
#define LROT_TABLE(t) static const LUA_REG_TYPE t ## _map[];
#define LROT_PUBLIC_TABLE(t) const LUA_REG_TYPE t ## _map[];
#define LROT_TABLEREF(t) ((void *) t ## _map)
#define LROT_BEGIN(t) static const LUA_REG_TYPE t ## _map [] = {
#define LROT_PUBLIC_BEGIN(t) const LUA_REG_TYPE t ## _map[] = {
#define LROT_EXTERN(t) extern const LUA_REG_TYPE t ## _map[]
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t ## _map)},
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA((void *) x)},
#define LROT_END(t,mt, f) {NULL, LRO_NILVAL} };
#define LROT_BREAK(t) };
#define LUA_REG_TYPE luaR_entry
#define LREGISTER(L, name, table) return 0
/* Maximum length of a rotable name and of a string key*/
#define LUA_MAX_ROTABLE_NAME 32
/* Type of a numeric key in a rotable */
typedef int luaR_numkey;
/* An entry in the read only table */
typedef struct luaR_entry {
const char *key;
const TValue value;
} luaR_entry;
/*
* The current ROTable implmentation is a vector of luaR_entry terminated by a
* nil record. The convention is to use ROtable * to refer to the entire vector
* as a logical ROTable.
*/
typedef const struct luaR_entry ROTable;
const TValue* luaR_findentry(ROTable *tab, TString *key, unsigned *ppos);
const TValue* luaR_findentryN(ROTable *tab, luaR_numkey numkey, unsigned *ppos);
void luaR_next(lua_State *L, ROTable *tab, TValue *key, TValue *val);
void* luaR_getmeta(ROTable *tab);
int luaR_isrotable(void *p);
/*
* Set inRO check depending on platform. Note that this implementation needs
* to work on both the host (luac.cross) and ESP targets. The luac.cross
* VM is used for the -e option, and is primarily used to be able to debug
* VM changes on the more developer-friendly hot gdb environment.
*/
#if defined(LUA_CROSS_COMPILER)
#if defined(_MSC_VER)
//msvc build uses these dummy vars to locate the beginning and ending addresses of the RO data
extern const char _ro_start[], _ro_end[];
#define IN_RODATA_AREA(p) (((const char*)(p)) >= _ro_start && ((const char *)(p)) <= _ro_end)
#else /* one of the POSIX variants */
#if defined(__CYGWIN__)
#define _RODATA_END __end__
#elif defined(__MINGW32__)
#define _RODATA_END end
#else
#define _RODATA_END _edata
#endif
extern const char _RODATA_END[];
#define IN_RODATA_AREA(p) (((const char *)(p)) < _RODATA_END)
#endif /* defined(_MSC_VER) */
#else /* xtensa tool chain for ESP target */
extern const char _irom0_text_start[];
extern const char _irom0_text_end[];
#define IN_RODATA_AREA(p) (((const char *)(p)) >= _irom0_text_start && ((const char *)(p)) <= _irom0_text_end)
#endif /* defined(LUA_CROSS_COMPILER) */
/* Return 1 if the given pointer is a rotable */
#define luaR_isrotable(p) IN_RODATA_AREA(p)
#endif
......@@ -7,7 +7,6 @@
#define lstate_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
......@@ -230,9 +229,6 @@ lua_State *lua_open(void) {
return lua_crtstate;
}
lua_State *lua_getstate(void) {
return lua_crtstate;
}
LUA_API void lua_close (lua_State *L) {
#ifndef LUA_CROSS_COMPILER
lua_sethook( L, NULL, 0, 0 );
......
......@@ -56,7 +56,7 @@ typedef struct CallInfo {
#define curr_func(L) (ttisfunction(L->ci->func) ? clvalue(L->ci->func) : NULL)
#define curr_func(L) (ttisclfunction(L->ci->func) ? clvalue(L->ci->func) : NULL)
#define ci_func(ci) (ttisfunction((ci)->func) ? clvalue((ci)->func) : NULL)
#define f_isLua(ci) (!ttislightfunction((ci)->func) && !ci_func(ci)->c.isC)
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
......@@ -160,7 +160,7 @@ union GCObject {
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
#define gco2u(o) (&rawgco2u(o)->uv)
#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
#define gco2h(o) check_exp(((o)->gch.tt & LUA_TMASK) == LUA_TTABLE, &((o)->h))
#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
#define ngcotouv(o) \
......
......@@ -8,7 +8,6 @@
#define lstring_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
......@@ -18,8 +17,6 @@
#include "lstate.h"
#include "lstring.h"
#define LUAS_READONLY_STRING 1
#define LUAS_REGULAR_STRING 0
void luaS_resize (lua_State *L, int newsize) {
stringtable *tb;
......@@ -53,26 +50,20 @@ void luaS_resize (lua_State *L, int newsize) {
}
static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h, int readonly) {
unsigned int h) {
TString *ts;
stringtable *tb;
stringtable *tb = &G(L)->strt;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
tb = &G(L)->strt;
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (readonly ? sizeof(char**) : (l+1)*sizeof(char))));
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (l+1)*sizeof(char)));
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L));
ts->tsv.tt = LUA_TSTRING;
if (!readonly) {
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else {
*(char **)(ts+1) = (char *)str;
l_setbit((ts)->tsv.marked, READONLYBIT);
}
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */
tb->hash[h] = obj2gco(ts);
......@@ -80,14 +71,6 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts;
}
static int lua_is_ptr_in_ro_area(const char *p) {
#ifdef LUA_CROSS_COMPILER
return 0; // TStrings are never in RO in luac.cross
#else
return IN_RODATA_AREA(p);
#endif
}
/*
* The string algorithm has been modified to be LFS-friendly. The previous eLua
* algo used the address of the string was in flash and the string was >4 bytes
......@@ -128,11 +111,7 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
}
}
#endif
/* New additions to the RAM strt are tagged as readonly if the string address
* is in the CTEXT segment (target only, not luac.cross) */
int readonly = (lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) &&
l == strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING);
return newlstr(L, str, l, h, readonly); /* not found */
return newlstr(L, str, l, h); /* not found */
}
......
......@@ -13,8 +13,7 @@
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+(testbit(getmarked(s), READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
......
......@@ -7,7 +7,6 @@
#define lstrlib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
......@@ -15,7 +14,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
......@@ -824,7 +823,21 @@ static int str_format (lua_State *L) {
return 1;
}
LROT_PUBLIC_BEGIN(strlib)
static int str_format2 (lua_State *L) {
if (lua_type(L, 2) == LUA_TTABLE) {
int i,n=lua_objlen(L,2);
lua_settop(L,2);
for (i = 1; i <= n; i++)
lua_rawgeti(L, 2, i);
lua_remove(L, 2);
}
return str_format(L);
}
LROT_BEGIN(strlib, NULL, LROT_MASK_INDEX)
LROT_TABENTRY( __index, strlib )
LROT_FUNCENTRY( __mod, str_format2 )
LROT_FUNCENTRY( byte, str_byte )
LROT_FUNCENTRY( char, str_char )
LROT_FUNCENTRY( dump, str_dump )
......@@ -844,8 +857,7 @@ LROT_PUBLIC_BEGIN(strlib)
LROT_FUNCENTRY( reverse, str_reverse )
LROT_FUNCENTRY( sub, str_sub )
LROT_FUNCENTRY( upper, str_upper )
LROT_TABENTRY( __index, strlib )
LROT_END(strlib, NULL, 0) // OR DO WE NEED LRTO_MASK_INDEX **TODO**
LROT_END(strlib, NULL, LROT_MASK_INDEX)
/*
** Open string library
......
......@@ -20,7 +20,6 @@
#define ltable_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <math.h>
......@@ -33,7 +32,8 @@
#include "lobject.h"
#include "lstate.h"
#include "ltable.h"
#include "lrotable.h"
#include "lstring.h"
/*
** max size of array part is 2^MAXBITS
......@@ -68,6 +68,10 @@
*/
#define numints cast_int(sizeof(lua_Number)/sizeof(int))
static const TValue* rotable_findentry(ROTable *rotable, TString *key, unsigned *ppos);
static void rotable_next_helper(lua_State *L, ROTable *pentries, int pos,
TValue *key, TValue *val);
static void rotable_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val);
#define dummynode (&dummynode_)
......@@ -105,11 +109,11 @@ static Node *mainposition (const Table *t, const TValue *key) {
return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TROTABLE:
return hashpointer(t, rvalue(key));
case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTFUNCTION:
return hashpointer(t, pvalue(key));
case LUA_TROTABLE:
return hashpointer(t, hvalue(key));
default:
return hashpointer(t, gcvalue(key));
}
......@@ -163,7 +167,12 @@ static int findindex (lua_State *L, Table *t, StkId key) {
int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */
int i;
if (isrotable(t)) {
rotable_next(L, (ROTable *) t, key, key+1);
return ttisnil(key) ? 0 : 1;
}
i = findindex(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setnvalue(key, cast_num(i+1));
......@@ -182,12 +191,6 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
}
int luaH_next_ro (lua_State *L, void *t, StkId key) {
luaR_next(L, t, key, key+1);
return ttisnil(key) ? 0 : 1;
}
/*
** {=============================================================
** Rehash
......@@ -563,6 +566,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
** search function for integers
*/
const TValue *luaH_getnum (Table *t, int key) {
if (isrotable(t))
return luaO_nilobject;
/* (1 <= key && key <= t->sizearray) */
if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
return &t->array[key-1];
......@@ -578,17 +583,16 @@ const TValue *luaH_getnum (Table *t, int key) {
}
}
/* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) {
const TValue *res = NULL; // integer values not supported: luaR_findentryN(t, key, NULL);
return res ? res : luaO_nilobject;
}
/*
** search function for strings
*/
const TValue *luaH_getstr (Table *t, TString *key) {
if (isrotable(t)) {
if (key->tsv.len>LUA_MAX_ROTABLE_NAME)
return luaO_nilobject;
return rotable_findentry((ROTable*) t, key, NULL);
}
Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */
if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
......@@ -598,63 +602,41 @@ const TValue *luaH_getstr (Table *t, TString *key) {
return luaO_nilobject;
}
/* same thing for rotables */
const TValue *luaH_getstr_ro (void *t, TString *key) {
if (!t || key->tsv.len>LUA_MAX_ROTABLE_NAME)
return luaO_nilobject;
return luaR_findentry(t, key, NULL);
}
/*
** main search function
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum(t, k); /* use specialized version */
/* else go through */
}
default: {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}
}
/* same thing for rotables */
const TValue *luaH_get_ro (void *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr_ro(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum_ro(t, k); /* use specialized version */
/* else go through */
}
default: {
return luaO_nilobject;
}
int type = ttype(key);
if (type == LUA_TNIL)
return luaO_nilobject;
if (type == LUA_TSTRING)
return luaH_getstr(t, rawtsvalue(key));
if (isrotable(t))
return luaO_nilobject;
if (type == LUA_TNUMBER) {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum(t, k); /* use specialized version */
}
/* default */
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_get(t, key);
t->flags = 0;
if (p != luaO_nilobject)
return cast(TValue *, p);
......@@ -668,7 +650,10 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
TValue *luaH_setnum (lua_State *L, Table *t, int key) {
const TValue *p = luaH_getnum(t, key);
const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_getnum(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
......@@ -680,7 +665,10 @@ TValue *luaH_setnum (lua_State *L, Table *t, int key) {
TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
const TValue *p = luaH_getstr(t, key);
const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_getstr(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
......@@ -720,7 +708,10 @@ static int unbound_search (Table *t, unsigned int j) {
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
int luaH_getn (Table *t) {
unsigned int j = t->sizearray;
unsigned int j;
if(isrotable(t))
return 0;
j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0;
......@@ -737,13 +728,138 @@ int luaH_getn (Table *t) {
else return unbound_search(t, j);
}
/* same thing for rotables */
int luaH_getn_ro (void *t) {
return 0; // Integer Keys are not currently supported for ROTables
}
int luaH_isdummy (Node *n) { return n == dummynode; }
/*
** All keyed ROTable access passes through rotable_findentry(). ROTables
** are simply a list of <key><TValue value> pairs.
**
** The global KeyCache is used to avoid a relatively expensive Flash memory
** vector scan. A simple hash on the key's TString addr and the ROTable
** addr selects the cache line. The line's slots are then scanned for a
** hit.
**
** Unlike the standard hast which uses a prime line count therefore requires
** the use of modulus operation which is expensive on an IoT processor
** without H/W divide. This hash is power of 2 based which might not be
** quite so uniform but can be calcuated without using H/W-based instructions.
**
** If a match is found and the table addresses match, then this entry is
** probed first. In practice the hit-rate here is over 99% so the code
** rarely fails back to doing the linear scan in ROM.
** Note that this hash does a couple of prime multiples and a modulus 2^X
** with is all evaluated in H/W, and adequately randomizes the lookup.
*/
#define LA_LINES 32
#define LA_SLOTS 4
static size_t cache [LA_LINES][LA_SLOTS];
#define HASH(a,b) ((((29*(size_t)(a)) ^ (37*((b)->tsv.hash)))>>4) % LA_LINES)
#define NDX_SHFT 24
#define ADDR_MASK (((size_t) 1<<24)-1)
/*
* Find a string key entry in a rotable and return it. Note that this internally
* uses a null key to denote a metatable search.
*/
static const TValue* rotable_findentry(ROTable *t, TString *key, unsigned *ppos) {
const ROTable_entry *e = cast(const ROTable_entry *, t->entry);
const int tl = getlsizenode(t);
const char *strkey = getstr(key);
size_t *cl = cache[HASH(t, key)];
int i, j = 1, l;
if (!e || gettt(key) != LUA_TSTRING)
return luaO_nilobject;
l = key->tsv.len;
/* scan the ROTable lookaside cache and return if hit found */
for (i=0; i<LA_SLOTS; i++) {
int cl_ndx = cl[i] >> NDX_SHFT;
if ((((size_t)t - cl[i]) & ADDR_MASK) == 0 && cl_ndx < tl &&
strcmp(e[cl_ndx].key, strkey) == 0) {
if (ppos)
*ppos = cl_ndx;
return &e[cl_ndx].value;
}
}
/*
* A lot of search misses are metavalues, but tables typically only have at
* most a couple of them, so these are always put at the front of the table
* in ascending order and the metavalue scan short circuits using a straight
* strcmp()
*/
lu_int32 name4 = *(lu_int32 *) strkey;
if (*(char*)&name4 == '_') {
for(i = 0; i < tl; i++) {
j = strcmp(e[i].key, strkey);
if (j>=0)
break;
}
} else {
/*
* Ordinary (non-meta) keys can be unsorted. This is for legacy compatiblity,
* plus misses are pretty rare in this case. The masked name4 comparison is
* safe 4-byte comparison that nearly always avoids the more costly strcmp()
* for an actual hit validation.
*/
lu_int32 mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
for(i = 0; i < tl; i++) {
if (((*(lu_int32 *)e[i].key ^ name4) & mask4) != 0)
continue;
j = strcmp(e[i].key, strkey);
if (j==0)
break;
}
}
if (j)
return luaO_nilobject;
if (ppos)
*ppos = i;
/* In the case of a hit, update the lookaside cache */
for (j = LA_SLOTS-1; j>0; j--)
cl[j] = cl[j-1];
cl[0] = ((size_t)t & ADDR_MASK) + (i << NDX_SHFT);
return &e[i].value;
}
static void rotable_next_helper(lua_State *L, ROTable *t, int pos,
TValue *key, TValue *val) {
const ROTable_entry *e = cast(const ROTable_entry *, t->entry);
if (pos < getlsizenode(t)) {
/* Found an entry */
setsvalue(L, key, luaS_new(L, e[pos].key));
setobj2s(L, val, &e[pos].value);
} else {
setnilvalue(key);
setnilvalue(val);
}
}
/* next (used for iteration) */
static void rotable_next(lua_State *L, ROTable *t, TValue *key, TValue *val) {
unsigned keypos = getlsizenode(t);
/* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key))
rotable_next_helper(L, t, 0, key, val);
else if (ttisstring(key)) {
/* Find the previous key again */
if (ttisstring(key)) {
rotable_findentry(t, rawtsvalue(key), &keypos);
}
/* Advance to next key */
rotable_next_helper(L, t, ++keypos, key, val);
}
}
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key);
......
......@@ -16,7 +16,8 @@
#define gnext(n) ((n)->i_key.nk.next)
#define key2tval(n) (&(n)->i_key.tvk)
#define isrotable(t) (gettt(t)==LUA_TROTABLE)
#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);
......@@ -36,6 +37,8 @@ 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
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
#endif
......
......@@ -7,13 +7,12 @@
#define ltablib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
......@@ -22,7 +21,7 @@
static int foreachi (lua_State *L) {
int i;
int n = aux_getn(L, 1);
luaL_checkanyfunction(L, 2);
luaL_checkfunction(L, 2);
for (i=1; i <= n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushinteger(L, i); /* 1st argument */
......@@ -38,7 +37,7 @@ static int foreachi (lua_State *L) {
static int foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanyfunction(L, 2);
luaL_checkfunction(L, 2);
lua_pushnil(L); /* first key */
while (lua_next(L, 1)) {
lua_pushvalue(L, 2); /* function */
......@@ -266,7 +265,7 @@ static int sort (lua_State *L) {
/* }====================================================== */
LROT_PUBLIC_BEGIN(tab_funcs)
LROT_BEGIN(tab_funcs, NULL, 0)
LROT_FUNCENTRY( concat, tconcat )
LROT_FUNCENTRY( foreach, foreach )
LROT_FUNCENTRY( foreachi, foreachi )
......
......@@ -5,37 +5,35 @@
*/
#include <string.h>
#define ltm_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
#include "lobject.h"
#include "lstate.h"
#include "lgc.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lrotable.h"
/* These must be correspond to the LUA_T* defines in lua.h */
const char *const luaT_typenames[] = {
"nil", "boolean", "romtable", "lightfunction", "userdata", "number",
"string", "table", "function", "userdata", "thread",
"nil", "boolean", "lightfunction","number", // base type = 0, 1, 2, 3
"string", "table", "function", "userdata", "thread", // base type = 4, 5, 6, 7, 8
"proto", "upval"
};
void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex",
"__gc", "__mode", "__eq",
"__add", "__sub", "__mul", "__div", "__mod",
"__pow", "__unm", "__len", "__lt", "__le",
"__concat", "__call"
"__concat", "__call",
"__metatable"
};
int i;
for (i=0; i<TM_N; i++) {
......@@ -50,22 +48,14 @@ void luaT_init (lua_State *L) {
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm;
const TValue *tm = luaH_getstr(events, ename);
lua_assert(event <= TM_EQ);
if (luaR_isrotable(events)) {
tm = luaH_getstr_ro(events, ename);
if (ttisnil(tm)) { /* no tag method? */
if (isrwtable(events)) /* if this a (RW) Table */
events->flags |= cast_byte(1u<<event); /* then cache this fact */
return NULL;
}
} else {
tm = luaH_getstr(events, ename);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */
return NULL;
}
}
return tm;
else return tm;
}
......@@ -73,21 +63,14 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
switch (ttype(o)) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(o));
mt = hvalue(o)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(o)->metatable;
break;
default:
mt = G(L)->mt[ttype(o)];
mt = G(L)->mt[basettype(o)];
}
if (!mt)
return luaO_nilobject;
else if (luaR_isrotable(mt))
return luaH_getstr_ro(mt, G(L)->tmname[event]);
else
return luaH_getstr(mt, G(L)->tmname[event]);
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}
......@@ -7,10 +7,6 @@
#ifndef ltm_h
#define ltm_h
#include "lobject.h"
#include "lrotable.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM"
......@@ -33,13 +29,16 @@ typedef enum {
TM_LE,
TM_CONCAT,
TM_CALL,
TM_METATABLE,
TM_N /* number of elements in the enum */
} TMS;
//#include "lobject.h"
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
(!luaR_isrotable(et) && ((et)->flags & (1u<<(e)))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
(getflags(et) & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l,et,e) gfasttm(G(l), et, e)
#define fasttm(l,et,e) gfasttm(G(l), et, e)
LUAI_DATA const char *const luaT_typenames[];
......
/*
** NodeMCU Lua 5.1 main initiator and comand interpreter
** See Copyright Notice in lua.h
**
** Note this is largely a backport of some new Lua 5.3 version but
** with API changes for Lua 5.1 compatability
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "user_version.h"
#include "driver/input.h"
#define lua_c
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "legc.h"
#include "llimits.h"
#define LUA_VERSION_51
#include "os_type.h"
#include "../lua53/lua.c"
extern int debug_errorfb (lua_State *L);
extern int pipe_create(lua_State *L);
extern int pipe_read(lua_State *L);
extern int pipe_unread(lua_State *L);
#ifndef LUA_INIT_STRING
#define LUA_INIT_STRING "@init.lua"
#endif
static int MLref = LUA_NOREF;
lua_State *globalL = NULL;
static int pmain (lua_State *L);
static int dojob (lua_State *L);
static void l_message (const char *msg) {
luai_writestringerror("%s\n", msg);
}
static int report (lua_State *L, int status) {
if (status && !lua_isnil(L, -1)) {
const char *msg = lua_tostring(L, -1);
if (msg == NULL) msg = "(error object is not a string)";
l_message(msg);
lua_pop(L, 1);
}
return status;
}
static void l_print(lua_State *L, int n) {
lua_getglobal(L, "print");
lua_insert(L, -n-1);
if (lua_pcall(L, n, 0, 0) != 0)
l_message(lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)",
lua_tostring(L, -1)));
}
static int traceback (lua_State *L) {
if (lua_isstring(L, 1)) {
lua_pushlightfunction(L, &debug_errorfb);
lua_pushvalue(L, 1); /* pass error message */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback */
}
lua_settop(L, 1);
return 1;
}
static int docall (lua_State *L, int narg, int clear) {
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushlightfunction(L, &traceback); /* push traceback function */
lua_insert(L, base); /* put it under chunk and args */
status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base);
lua_remove(L, base); /* remove traceback function */
/* force a complete garbage collection in case of errors */
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
return status;
}
static void print_version (lua_State *L) {
lua_pushliteral (L, "\n" NODE_VERSION " build " BUILD_DATE
" powered by " LUA_RELEASE " on SDK ");
lua_pushstring (L, SDK_VERSION);
lua_concat (L, 2);
const char *msg = lua_tostring (L, -1);
l_message (msg);
lua_pop (L, 1);
}
static int dofile (lua_State *L, const char *name) {
int status = luaL_loadfile(L, name) || docall(L, 0, 1);
return report(L, status);
}
static int dostring (lua_State *L, const char *s, const char *name) {
int status = luaL_loadbuffer(L, s, strlen(s), name) || docall(L, 0, 1);
return report(L, status);
}
static const char *get_prompt (lua_State *L, int firstline) {
const char *p;
lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
p = lua_tostring(L, -1);
if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
lua_pop(L, 1); /* remove global */
return p;
}
#define EOFMARK LUA_QL("<eof>")
static int incomplete (lua_State *L, int status) {
if (status == LUA_ERRSYNTAX) {
size_t lmsg;
const char *msg = lua_tolstring(L, -1, &lmsg);
if (!strcmp(msg+lmsg-sizeof(EOFMARK)+1, EOFMARK)) {
lua_pop(L, 1);
return 1;
}
}
return 0;
}
/*
** dojob is the CB reader for the input pipe and follows the calling convention
** for pipe reader CBs. It has one argument: the stdin pipe that it is reading.
*/
static int dojob (lua_State *L) {
size_t l;
int status;
const char *prompt;
//dbg_printf("dojob entered\n");
lua_settop(L, 1); /* pipe obj at S[1] */
lua_pushlightfunction(L, &pipe_read); /* pobj:read at S[2] */
lua_pushvalue(L, 1); /* dup pobj to S[3] */
lua_pushliteral(L, "\n+"); /* S[4] = "\n+" */
lua_call(L, 2, 1); /* S[2] = pobj:read("\n+") */
const char* b = lua_tolstring(L, 2, &l); /* b = NULL if S[2] is nil */
if ((lua_isnil(L, 2) || l == 0)) {
/* If the pipe is empty then return false to suppress automatic reposting */
//dbg_printf("stdin empty\n");
lua_pushboolean(L, false);
return 1; /* return false */
}
if (b[l-1] != '\n') {
//dbg_printf("unreading part line\n");
/* likewise if not CR terminated, then unread and ditto */
lua_pushlightfunction(L, &pipe_unread); /* pobj:read at S[1] */
lua_insert(L, 1);
lua_call(L, 2, 0); /* pobj:unread(line) */
lua_pushboolean(L, false);
return 1; /* return false */
} else {
//dbg_printf("popping CR terminated string(%d) %s", l-1, b);
}
/*
* Now we can process a proper CR terminated line
*/
lua_pushlstring(L, b, --l); /* remove end CR */
lua_remove(L, 2);
b = lua_tostring(L, 2);
if (MLref != LUA_NOREF) {
/* processing multiline */
lua_rawgeti(L, LUA_REGISTRYINDEX, MLref); /* insert prev lines(s) */
lua_pushliteral(L, "\n"); /* insert CR */
lua_pushvalue(L, 2); /* dup new line */
lua_concat(L, 3); /* concat all 3 */
lua_remove(L, 2); /* and shift down to S[2] */
} else if (b[0] == '=') {
/* If firstline and of the format =<expression> */
lua_pushfstring(L, "return %s", b+1);
lua_remove(L, 2);
}
/* ToS is at S[2] which contains the putative chunk to be compiled */
status = luaL_loadbuffer(L, lua_tostring(L, 2), lua_strlen(L, 2), "=stdin");
if (incomplete(L, status)) {
/* Store line back in the Reg mlref sot */
if (MLref == LUA_NOREF) {
MLref = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
lua_rawseti(L, LUA_REGISTRYINDEX, MLref);
}
} else {
/* compile finished OK or with hard error */
lua_remove(L, 2); /* remove line because now redundant */
if (MLref!= LUA_NOREF) { /* also remove multiline if it exists */
luaL_unref(L, LUA_REGISTRYINDEX, MLref);
MLref= LUA_NOREF;
}
/* Execute the compiled chunk of successful */
if (status == 0) {
status = docall(L, 0, 0);
}
/* print any returned results or error message */
if (status && !lua_isnil(L, -1))
l_print(L, 1);
if (status == 0 && lua_gettop(L) - 1)
l_print(L, lua_gettop(L) - 1);
lua_settop(L, 2);
if (status != 0) lua_gc(L, LUA_GCCOLLECT, 0);
}
prompt = get_prompt(L, MLref!= LUA_NOREF ? 0 : 1);
input_setprompt(prompt);
puts(prompt);
lua_pushnil(L);
return 1; /* return nil will retask if pipe not empty */
}
/*
* Kick off library and UART input handling before opening the module
* libraries. Note that as this is all done within a Lua task, so error
* handling is left to the Lua task traceback mechanism.
*/
extern void luaL_dbgbreak(void);
static int pmain (lua_State *L) {
const char *init = LUA_INIT_STRING;
globalL = L;
lua_gc(L, LUA_GCSTOP, 0); /* stop GC during initialization */
luaL_openlibs(L); /* open libraries */
lua_gc(L, LUA_GCRESTART, 0); /* restart GC and set EGC mode */
legc_set_mode( L, EGC_ALWAYS, 4096 );
lua_settop(L, 0);
lua_pushliteral(L, "stdin");
lua_pushlightfunction(L, &pipe_create);
lua_pushlightfunction(L, &dojob);
lua_pushinteger(L, LUA_TASK_LOW);
lua_call(L, 2, 1); /* ToS = pipe.create(dojob, low_priority) */
lua_rawset(L, LUA_REGISTRYINDEX); /* and stash input pipe in Reg["stdin"] */
input_setup(LUA_MAXINPUT, get_prompt(L, 1));
lua_input_string(" \n", 2); /* queue CR to issue first prompt */
#if !defined(DISABLE_STARTUP_BANNER)
print_version(L);
#endif
/* and last of all, kick off application initialisation */
if (init[0] == '@')
dofile(L, init+1);
else
dostring(L, init, LUA_INIT);
return 0;
}
/*
** The system initialisation CB nodemcu_init() calls lua_main() to startup
** the Lua environment by calling lua_open() which initiates the core Lua VM.
** The initialisation of the libraries, etc. is carried out by pmain in a
** separate Lua task, which also kicks off the user application through the
** LUA_INIT_STRING hook.
*/
void lua_main (void) {
lua_State *L = lua_open(); /* create state */
if (L == NULL) {
l_message("cannot create state: not enough memory");
return;
}
lua_pushlightfunction(L, &pmain); /* Call 'pmain' as a high priority task */
luaN_posttask(L, LUA_TASK_HIGH);
}
/*
** The Lua interpreter is event-driven and task-oriented in NodeMCU rather than
** based on a readline poll loop as in the standard implementation. Input lines
** can come from one of two sources: the application can "push" lines for the
** interpreter to compile and execute, or they can come from the UART. To
** minimise application blocking, the lines are queued in a pipe when received,
** with the Lua interpreter task attached to the pipe as its reader task. This
** CB processes one line of input per task execution.
**
** Even though lines can be emitted from independent sources (the UART and the
** node API), and they could in theory get interleaved, the strategy here is
** "let the programmer beware": interactive input will normally only occur in
** development and injected input occur in telnet type applications. If there
** is a need for interlocks, then the application should handle this.
*/
//static int n = 0;
void lua_input_string (const char *line, int len) {
lua_State *L = globalL;
lua_getfield(L, LUA_REGISTRYINDEX, "stdin");
lua_rawgeti(L, -1, 1); /* get the pipe_write from stdin[1] */
lua_insert(L, -2); /* stick above the pipe */
lua_pushlstring(L, line, len);
//const char*b = lua_tostring(L, -1);
//dbg_printf("Pushing (%u): %s", len, b);
lua_call(L, 2, 0); /* stdin:write(line) */
}
......@@ -8,9 +8,6 @@
#ifndef lua_h
#define lua_h
#ifdef LUAC_CROSS_FILE
#include "luac_cross.h"
#endif
#include <stdint.h>
#include "stdarg.h"
#include "stddef.h"
......@@ -42,7 +39,8 @@
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
/* thread status; 0 is OK */
/* thread status */
#define LUA_OK 0
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
......@@ -73,18 +71,22 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TROTABLE 2
#define LUA_TLIGHTFUNCTION 3
#define LUA_TLIGHTUSERDATA 4
#define LUA_TNUMBER 5
#define LUA_TSTRING 6
#define LUA_TTABLE 7
#define LUA_TFUNCTION 8
#define LUA_TUSERDATA 9
#define LUA_TTHREAD 10
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_TISROTABLE (1<<4)
#define LUA_TISLIGHTFUNC (1<<5)
#define LUA_TMASK 15
#define LUA_TROTABLE (LUA_TTABLE + LUA_TISROTABLE)
#define LUA_TLIGHTFUNCTION (LUA_TFUNCTION + LUA_TISLIGHTFUNC)
/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
......@@ -143,6 +145,7 @@ LUA_API int (lua_isstring) (lua_State *L, int idx);
LUA_API int (lua_iscfunction) (lua_State *L, int idx);
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
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);
......@@ -174,8 +177,6 @@ LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API void (lua_pushlightfunction) (lua_State *L, void *p);
LUA_API void (lua_pushrotable) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);
......@@ -212,7 +213,7 @@ 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_dump) (lua_State *L, lua_Writer writer, void *data);
LUA_API int (lua_dumpEx) (lua_State *L, lua_Writer writer, void *data, int stripping);
/*
......@@ -272,11 +273,9 @@ 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_type(L, (n)) == LUA_TLIGHTFUNCTION)
#define lua_isanyfunction(L,n) (lua_isfunction(L,n) || lua_islightfunction(L,n))
#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_type(L, (n)) == LUA_TROTABLE)
#define lua_isanytable(L,n) (lua_istable(L,n) || lua_isrotable(L,n))
#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)
......@@ -292,14 +291,20 @@ 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)
/* error codes from cross-compiler returned by lua_dumpEx */
/* target integer is too small to hold a value */
#define LUA_ERR_CC_INTOVERFLOW 101
/* target lua_Number is integral but a constant is non-integer */
#define LUA_ERR_CC_NOTINTEGER 102
/*
** compatibility macros and functions
*/
// BogdanM: modified for eLua interrupt support
//#define lua_open() luaL_newstate()
lua_State* lua_open(void);
lua_State* lua_getstate(void);
......@@ -377,20 +382,46 @@ struct lua_Debug {
/* }====================================================================== */
typedef struct ROTable ROTable;
typedef 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, const ROTable_entry *e, ROTable *mt);
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
#ifdef LUA_USE_ESP
#ifndef LUA_CROSS_COMPILER
#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
void lua_main (void);
void lua_input_string (const char *line, int len);
int luaN_posttask (lua_State* L, int prio);
int luaN_call (lua_State *L, int narg, int res, int dogc);
/**DEBUG**/extern void dbg_printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 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));
LUA_API void lua_setegcmode(lua_State *L, int mode, int limit);
#else
#define ICACHE_RODATA_ATTR
#define dbg_printf printf
#endif
extern void lua_debugbreak(void);
// EGC operations modes
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
void legc_set_mode(lua_State *L, int mode, int limit);
/******************************************************************************
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
......
/*
** Header to allow luac.cross compile within NodeMCU
** See Copyright Notice in lua.h
*/
#ifndef luac_cross_h
#define luac_cross_h
#ifdef LUA_CROSS_COMPILER
#define ICACHE_RODATA_ATTR
#define c_stderr stderr
#define c_stdin stdin
#define c_stdout stdout
#define dbg_printf printf
#else
#endif /* LUA_CROSS_COMPILER */
#endif /* luac_cross_h */
......@@ -8,30 +8,41 @@
summary ?= @true
CCFLAGS:= -I.. -I../../include -I../../uzlib
CCFLAGS:= -I. -I.. -I../../include -I../../uzlib
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -ldl -Wl,-Map=mapfile
CCFLAGS += -Wall
DEFINES += -DLUA_CROSS_COMPILER
TARGET = host
ifeq ($(FLAVOR),debug)
CCFLAGS += -O0 -g
TARGET_LDFLAGS += -O0 -g
DEFINES += -DLUA_DEBUG_BUILD
VERBOSE ?=
V ?= $(VERBOSE)
ifeq ("$(V)","1")
export summary := @true
else
export summary := @echo
# disable echoing of commands, directory names
MAKEFLAGS += --silent -w
endif # $(V)==1
DEBUG ?=
ifeq ("$(DEBUG)","1")
FLAVOR = debug
CCFLAGS += -O0 -ggdb
TARGET_LDFLAGS += -O0 -ggdb
DEFINES += -DLUA_CROSS_COMPILER -DLUA_DEBUG_BUILD -DDEVELOPMENT_TOOLS -DDEVELOPMENT_USE_GDB
else
FLAVOR = release
CCFLAGS += -O2
TARGET_LDFLAGS += -O2
endif
DEFINES += -DLUA_CROSS_COMPILER
endif # DEBUG
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 \
lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
ltm.c lundump.c lvm.c lzio.c
UZSRC := uzlib_deflate.c crc32.c
......
......@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
......
......@@ -17,7 +17,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
......@@ -439,7 +439,10 @@ static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
LROT_PUBLIC_BEGIN(iolib)
LROT_TABLE(iolib);
LROT_BEGIN(iolib, NULL, LROT_MASK_GC_INDEX)
LROT_TABENTRY( __index, iolib )
LROT_FUNCENTRY( close, io_close )
LROT_FUNCENTRY( flush, io_flush )
LROT_FUNCENTRY( input, io_input )
......@@ -449,10 +452,14 @@ LROT_PUBLIC_BEGIN(iolib)
LROT_FUNCENTRY( read, io_read )
LROT_FUNCENTRY( type, io_type )
LROT_FUNCENTRY( write, io_write )
LROT_TABENTRY( __index, iolib )
LROT_END(iolib, NULL, 0)
LROT_END(iolib, NULL, LROT_MASK_GC_INDEX)
LROT_TABLE(flib);
LROT_BEGIN(flib)
LROT_BEGIN(flib, NULL, LROT_MASK_GC_INDEX)
LROT_FUNCENTRY( __gc, io_gc )
LROT_TABENTRY( __index, flib )
LROT_FUNCENTRY( __tostring, io_tostring )
LROT_FUNCENTRY( close, io_close )
LROT_FUNCENTRY( flush, f_flush )
LROT_FUNCENTRY( lines, f_lines )
......@@ -460,9 +467,6 @@ LROT_BEGIN(flib)
LROT_FUNCENTRY( seek, f_seek )
LROT_FUNCENTRY( setvbuf, f_setvbuf )
LROT_FUNCENTRY( write, f_write )
LROT_FUNCENTRY( __gc, io_gc )
LROT_FUNCENTRY( __tostring, io_tostring )
LROT_TABENTRY( __index, flib )
LROT_END(flib, NULL, LROT_MASK_GC_INDEX)
static const luaL_Reg io_base[] = {{NULL, NULL}};
......
......@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
......@@ -20,7 +19,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
......@@ -220,7 +219,7 @@ static int os_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS));
}
LROT_PUBLIC_BEGIN(oslib)
LROT_BEGIN(oslib, NULL, 0)
LROT_FUNCENTRY( clock, os_clock )
LROT_FUNCENTRY( date, os_date )
#if !defined LUA_NUMBER_INTEGRAL
......
......@@ -5,16 +5,15 @@
*/
#define LUAC_CROSS_FILE
#define luac_c
#define LUA_CORE
#include "luac_cross.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define luac_c
#define LUA_CORE
#include "lua.h"
#include "lauxlib.h"
......@@ -290,8 +289,8 @@ static int pmain(lua_State* L)
if (!lua_checkstack(L,argc)) fatal("too many input files");
if (execute)
{
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
luaL_openlibs(L);
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
lua_pushstring(L, execute);
if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
if (!lua_isfunction(L, -1))
......
......@@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h>
#include <stdio.h>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment