Unverified Commit b41667b8 authored by Marcel Stör's avatar Marcel Stör Committed by GitHub
Browse files

Master drop #2486

Dev -> Master Release 10
parents f99f295d 0abb2617
......@@ -79,6 +79,7 @@
#define VALUEWEAKBIT 4
#define FIXEDBIT 5
#define SFIXEDBIT 6
#define LFSBIT 6
#define READONLYBIT 7
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
......@@ -100,6 +101,13 @@
#define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT)
#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT)
#define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT)
#ifdef LUA_FLASH_STORE
#define isLFSobject(x) testbit((x)->marked, LFSBIT)
#define stringfix(s) if (!test2bits((s)->tsv.marked, FIXEDBIT, LFSBIT)) {l_setbit((s)->tsv.marked, FIXEDBIT);}
#else
#define isLFSobject(x) (0)
#define stringfix(s) {l_setbit((s)->tsv.marked, FIXEDBIT);}
#endif
#define luaC_checkGC(L) { \
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
......
/*
** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
#define linit_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "luaconf.h"
#include "module.h"
#if defined(LUA_CROSS_COMPILER)
BUILTIN_LIB( start_list, NULL, NULL);
BUILTIN_LIB_INIT( start_list, NULL, NULL);
#endif
extern const luaR_entry strlib[], tab_funcs[], dblib[],
co_funcs[], math_map[], syslib[];
BUILTIN_LIB_INIT( BASE, "", luaopen_base);
BUILTIN_LIB_INIT( LOADLIB, LUA_LOADLIBNAME, luaopen_package);
BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);
BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);
#if defined(LUA_CROSS_COMPILER)
extern const luaR_entry syslib[], iolib[];
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
BUILTIN_LIB_INIT( IO, LUA_IOLIBNAME, luaopen_io);
BUILTIN_LIB( end_list, NULL, NULL);
BUILTIN_LIB_INIT( end_list, NULL, NULL);
/*
* These base addresses are internal to this module for cross compile builds
* This also exploits feature of the GCC code generator that the variables are
* emitted in either normal OR reverse order within PSECT.
*/
#define isascending(n) ((&(n ## _end_list)-&(n ## _start_list))>0)
static const luaL_Reg *lua_libs;
const luaR_table *lua_rotable;
#else
/* These base addresses are Xtensa toolchain linker constants for Firmware builds */
extern const luaL_Reg lua_libs_base[];
extern const luaR_table lua_rotable_base[];
static const luaL_Reg *lua_libs = lua_libs_base;
const luaR_table *lua_rotable = lua_rotable_base;
#endif
void luaL_openlibs (lua_State *L) {
#if defined(LUA_CROSS_COMPILER)
lua_libs = (isascending(lua_lib) ? &lua_lib_start_list : &lua_lib_end_list) + 1;
lua_rotable = (isascending(lua_rotable) ? &lua_rotable_start_list : &lua_rotable_end_list) + 1;
#endif
const luaL_Reg *lib = lua_libs;
for (; lib->name; lib++) {
if (lib->func)
{
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
}
}
}
......@@ -326,7 +326,7 @@ const LUA_REG_TYPE math_map[] = {
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)},
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)},
#if LUA_OPTIMIZE_MEMORY > 0
{LSTRKEY("huge"), LNUMVAL(LONG_MAX)},
{LSTRKEY("huge"), LNUMVAL(INT_MAX)},
#endif
#else
{LSTRKEY("abs"), LFUNCVAL(math_abs)},
......@@ -374,7 +374,7 @@ const LUA_REG_TYPE math_map[] = {
*/
#if defined LUA_NUMBER_INTEGRAL
# include "c_limits.h" /* for LONG_MAX */
# include "c_limits.h" /* for INT_MAX */
#endif
LUALIB_API int luaopen_math (lua_State *L) {
......@@ -383,7 +383,7 @@ LUALIB_API int luaopen_math (lua_State *L) {
#else
luaL_register(L, LUA_MATHLIBNAME, math_map);
# if defined LUA_NUMBER_INTEGRAL
lua_pushnumber(L, LONG_MAX);
lua_pushnumber(L, INT_MAX);
lua_setfield(L, -2, "huge");
# else
lua_pushnumber(L, PI);
......
......@@ -613,7 +613,7 @@ static int ll_seeall (lua_State *L) {
static void setpath (lua_State *L, const char *fieldname, const char *envname,
const char *def) {
const char *path = c_getenv(envname);
const char *path = NULL; /* getenv(envname) not used in NodeMCU */;
if (path == NULL) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
......
......@@ -53,7 +53,8 @@ int luaO_fb2int (int x) {
int luaO_log2 (unsigned int x) {
static const lu_byte log_2[256] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = {
#ifdef LUA_CROSS_COMPILER
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
......@@ -65,10 +66,12 @@ int luaO_log2 (unsigned int x) {
};
int l = -1;
while (x >= 256) { l += 8; x >>= 8; }
#ifdef LUA_CROSS_COMPILER
return l + log_2[x];
#else
return l + byte_of_aligned_array(log_2,x);
/* Use Normalization Shift Amount Unsigned: 0x1=>31 up to 0xffffffff =>0
* See Xtensa Instruction Set Architecture (ISA) Refman P 462 */
asm volatile ("nsau %0, %1;" :"=r"(x) : "r"(x));
return 31 - x;
#endif
}
......@@ -103,7 +106,7 @@ int luaO_str2d (const char *s, lua_Number *result) {
#if defined(LUA_CROSS_COMPILER)
{
long lres = strtoul(s, &endptr, 16);
#if LONG_MAX != 2147483647L
#if INT_MAX != 2147483647L
if (lres & ~0xffffffffL)
*result = cast_num(-1);
else if (lres & 0x80000000L)
......
......@@ -23,10 +23,10 @@
#define NUM_TAGS (LAST_TAG+1)
/* mask for 'read-only' objects. must match READONLYBIT in lgc.h' */
#define READONLYMASK 128
#define READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */
#ifdef LUA_FLASH_STORE
#define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */
#endif
/*
** Extra tags for non-values
*/
......@@ -55,86 +55,39 @@ typedef struct GCheader {
CommonHeader;
} GCheader;
#if defined(LUA_PACK_VALUE) || defined(ELUA_ENDIAN_BIG) || defined(ELUA_ENDIAN_SMALL)
# error "NodeMCU does not support the eLua LUA_PACK_VALUE and ELUA_ENDIAN defines"
#endif
/*
** Union of all Lua values
*/
#if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
typedef union {
struct {
int _pad0;
GCObject *gc;
};
struct {
int _pad1;
void *p;
};
lua_Number n;
struct {
int _pad2;
int b;
};
} Value;
#else // #if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
typedef union {
GCObject *gc;
void *p;
lua_Number n;
int b;
} Value;
#endif // #if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
/*
** Tagged Values
*/
#ifndef LUA_PACK_VALUE
#define TValuefields Value value; int tt
#define LUA_TVALUE_NIL {NULL}, LUA_TNIL
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack(4)
#endif
typedef struct lua_TValue {
TValuefields;
} TValue;
#else // #ifndef LUA_PACK_VALUE
#ifdef ELUA_ENDIAN_LITTLE
#define TValuefields union { \
struct { \
int _pad0; \
int tt_sig; \
} _ts; \
struct { \
int _pad; \
short tt; \
short sig; \
} _t; \
Value value; \
}
#define LUA_TVALUE_NIL {0, add_sig(LUA_TNIL)}
#else // #ifdef ELUA_ENDIAN_LITTLE
#define TValuefields union { \
struct { \
int tt_sig; \
int _pad0; \
} _ts; \
struct { \
short sig; \
short tt; \
int _pad; \
} _t; \
Value value; \
}
#define LUA_TVALUE_NIL {add_sig(LUA_TNIL), 0}
#endif // #ifdef ELUA_ENDIAN_LITTLE
#define LUA_NOTNUMBER_SIG (-1)
#define add_sig(tt) ( 0xffff0000 | (tt) )
typedef TValuefields TValue;
#endif // #ifndef LUA_PACK_VALUE
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack()
#endif
/* Macros to test type */
#ifndef LUA_PACK_VALUE
#define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
......@@ -146,27 +99,11 @@ typedef TValuefields TValue;
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
#define ttisrotable(o) (ttype(o) == LUA_TROTABLE)
#define ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION)
#else // #ifndef LUA_PACK_VALUE
#define ttisnil(o) (ttype_sig(o) == add_sig(LUA_TNIL))
#define ttisnumber(o) ((o)->_t.sig != LUA_NOTNUMBER_SIG)
#define ttisstring(o) (ttype_sig(o) == add_sig(LUA_TSTRING))
#define ttistable(o) (ttype_sig(o) == add_sig(LUA_TTABLE))
#define ttisfunction(o) (ttype_sig(o) == add_sig(LUA_TFUNCTION))
#define ttisboolean(o) (ttype_sig(o) == add_sig(LUA_TBOOLEAN))
#define ttisuserdata(o) (ttype_sig(o) == add_sig(LUA_TUSERDATA))
#define ttisthread(o) (ttype_sig(o) == add_sig(LUA_TTHREAD))
#define ttislightuserdata(o) (ttype_sig(o) == add_sig(LUA_TLIGHTUSERDATA))
#define ttisrotable(o) (ttype_sig(o) == add_sig(LUA_TROTABLE))
#define ttislightfunction(o) (ttype_sig(o) == add_sig(LUA_TLIGHTFUNCTION))
#endif // #ifndef LUA_PACK_VALUE
/* Macros to access values */
#ifndef LUA_PACK_VALUE
#define ttype(o) ((o)->tt)
#else // #ifndef LUA_PACK_VALUE
#define ttype(o) ((o)->_t.sig == LUA_NOTNUMBER_SIG ? (o)->_t.tt : LUA_TNUMBER)
#define ttype_sig(o) ((o)->_ts.tt_sig)
#endif // #ifndef LUA_PACK_VALUE
#define ttype(o) ((void) (o)->value, (o)->tt)
#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
#define rvalue(o) check_exp(ttisrotable(o), (o)->value.p)
......@@ -186,24 +123,15 @@ typedef TValuefields TValue;
/*
** for internal debug only
*/
#ifndef LUA_PACK_VALUE
#define checkconsistency(obj) \
lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
#define checkliveness(g,obj) \
lua_assert(!iscollectable(obj) || \
((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
#else // #ifndef LUA_PACK_VALUE
#define checkconsistency(obj) \
lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch._t.tt))
#define checkliveness(g,obj) \
lua_assert(!iscollectable(obj) || \
((ttype(obj) == (obj)->value.gc->gch._t.tt) && !isdead(g, (obj)->value.gc)))
#endif // #ifndef LUA_PACK_VALUE
/* Macros to set values */
#ifndef LUA_PACK_VALUE
#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
#define setnvalue(obj,x) \
......@@ -257,69 +185,10 @@ typedef TValuefields TValue;
i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \
checkliveness(G(L),i_o); }
#define setobj(L,obj1,obj2) \
{ const TValue *o2=(obj2); TValue *o1=(obj1); \
o1->value = o2->value; o1->tt=o2->tt; \
checkliveness(G(L),o1); }
#else // #ifndef LUA_PACK_VALUE
#define setnilvalue(obj) ( ttype_sig(obj) = add_sig(LUA_TNIL) )
#define setnvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.n=(x); }
#define setpvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TLIGHTUSERDATA);}
#define setrvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TROTABLE);}
#define setfvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TLIGHTFUNCTION);}
#define setbvalue(obj,x) \
{ TValue *i_o=(obj); i_o->value.b=(x); i_o->_ts.tt_sig=add_sig(LUA_TBOOLEAN);}
#define setsvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TSTRING); \
checkliveness(G(L),i_o); }
#define setuvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TUSERDATA); \
checkliveness(G(L),i_o); }
#define setthvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TTHREAD); \
checkliveness(G(L),i_o); }
#define setclvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TFUNCTION); \
checkliveness(G(L),i_o); }
#define sethvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TTABLE); \
checkliveness(G(L),i_o); }
#define setptvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o->value.gc=cast(GCObject *, (x)); i_o->_ts.tt_sig=add_sig(LUA_TPROTO); \
checkliveness(G(L),i_o); }
#define setobj(L,obj1,obj2) \
{ const TValue *o2=(obj2); TValue *o1=(obj1); \
o1->value = o2->value; \
checkliveness(G(L),o1); }
#endif // #ifndef LUA_PACK_VALUE
/*
** different types of sets, according to destination
......@@ -340,13 +209,7 @@ typedef TValuefields TValue;
#define setobj2n setobj
#define setsvalue2n setsvalue
#ifndef LUA_PACK_VALUE
#define setttype(obj, tt) (ttype(obj) = (tt))
#else // #ifndef LUA_PACK_VALUE
/* considering it used only in lgc to set LUA_TDEADKEY */
/* we could define it this way */
#define setttype(obj, _tt) ( ttype_sig(obj) = add_sig(_tt) )
#endif // #ifndef LUA_PACK_VALUE
#define setttype(obj, stt) ((void) (obj)->value, (obj)->tt = (stt))
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
......@@ -367,9 +230,16 @@ typedef union TString {
} tsv;
} TString;
#define getstr(ts) (((ts)->tsv.marked & READONLYMASK) ? cast(const char *, *(const char**)((ts) + 1)) : cast(const char *, (ts) + 1))
#define svalue(o) getstr(rawtsvalue(o))
#ifdef LUA_CROSS_COMPILER
#define isreadonly(o) (0)
#else
#define isreadonly(o) ((o).marked & READONLYMASK)
#endif
#define ts_isreadonly(ts) isreadonly((ts)->tsv)
#define getstr(ts) (ts_isreadonly(ts) ? \
cast(const char *, *(const char**)((ts) + 1)) : \
cast(const char *, (ts) + 1))
#define svalue(o) getstr(rawtsvalue(o))
......@@ -418,6 +288,7 @@ typedef struct Proto {
lu_byte is_vararg;
lu_byte maxstacksize;
} Proto;
#define proto_isreadonly(p) isreadonly(*(p))
/* masks for new-style vararg */
......@@ -487,7 +358,6 @@ typedef union Closure {
** Tables
*/
#ifndef LUA_PACK_VALUE
typedef union TKey {
struct {
TValuefields;
......@@ -497,16 +367,6 @@ typedef union TKey {
} TKey;
#define LUA_TKEY_NIL {LUA_TVALUE_NIL, NULL}
#else // #ifndef LUA_PACK_VALUE
typedef struct TKey {
TValue tvk;
struct {
struct Node *next; /* for chaining */
} nk;
} TKey;
#define LUA_TKEY_NIL {LUA_TVALUE_NIL}, {NULL}
#endif // #ifndef LUA_PACK_VALUE
typedef struct Node {
TValue i_val;
......
......@@ -916,12 +916,11 @@ static int block_follow (int token) {
static void block (LexState *ls) {
/* block -> chunk */
FuncState *fs = ls->fs;
BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt));
enterblock(fs, pbl, 0);
BlockCnt bl;
enterblock(fs, &bl, 0);
chunk(ls);
lua_assert(pbl->breaklist == NO_JUMP);
lua_assert(bl.breaklist == NO_JUMP);
leaveblock(fs);
luaM_free(ls->L,pbl);
}
......@@ -1081,13 +1080,13 @@ static int exp1 (LexState *ls) {
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
/* forbody -> DO block */
BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt));
BlockCnt bl;
FuncState *fs = ls->fs;
int prep, endfor;
adjustlocalvars(ls, 3); /* control variables */
checknext(ls, TK_DO);
prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
enterblock(fs, pbl, 0); /* scope for declared variables */
enterblock(fs, &bl, 0); /* scope for declared variables */
adjustlocalvars(ls, nvars);
luaK_reserveregs(fs, nvars);
block(ls);
......@@ -1097,7 +1096,6 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
luaM_free(ls->L,pbl);
}
......
......@@ -15,7 +15,7 @@
#undef LNILVAL
#undef LREGISTER
#if (MIN_OPT_LEVEL > 0) && (LUA_OPTIMIZE_MEMORY >= MIN_OPT_LEVEL)
#if LUA_OPTIMIZE_MEMORY >=1
#define LUA_REG_TYPE luaR_entry
#define LSTRKEY LRO_STRKEY
#define LNUMKEY LRO_NUMKEY
......
......@@ -14,7 +14,7 @@
#define LUAR_FINDVALUE 1
/* Externally defined read-only table array */
extern const luaR_table lua_rotable[];
extern const luaR_table *lua_rotable;
/* Find a global "read only table" in the constant lua_rotable array */
void* luaR_findglobal(const char *name, unsigned len) {
......@@ -85,7 +85,7 @@ static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos,
if (pentries[pos].key.type != LUA_TNIL) {
/* Found an entry */
if (pentries[pos].key.type == LUA_TSTRING)
setsvalue(L, key, luaS_newro(L, pentries[pos].key.id.strkey))
setsvalue(L, key, luaS_new(L, pentries[pos].key.id.strkey))
else
setnvalue(key, (lua_Number)pentries[pos].key.id.numkey)
setobj2s(L, val, &pentries[pos].value);
......@@ -125,12 +125,22 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) {
}
}
/* Return 1 if the given pointer is a rotable */
#ifdef LUA_META_ROTABLES
#include "compiler.h"
#ifdef LUA_META_ROTABLES
/* Set in RO check depending on platform */
#if defined(LUA_CROSS_COMPILER) && defined(__CYGWIN__)
extern char __end__[];
#define IN_RO_AREA(p) ((p) < __end__)
#elif defined(LUA_CROSS_COMPILER)
extern char _edata[];
#define IN_RO_AREA(p) ((p) < _edata)
#else /* xtensa tool chain for ESP target */
extern char _irom0_text_start[];
extern char _irom0_text_end[];
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
#endif
/* Return 1 if the given pointer is a rotable */
int luaR_isrotable(void *p) {
return RODATA_START_ADDRESS <= (char*)p && (char*)p <= RODATA_END_ADDRESS;
return IN_RO_AREA((char *)p);
}
#endif
......@@ -4,32 +4,16 @@
#define lrotable_h
#include "lua.h"
#include "llimits.h"
#include "lobject.h"
#include "luaconf.h"
#include "lobject.h"
#include "llimits.h"
/* Macros one can use to define rotable entries */
#ifndef LUA_PACK_VALUE
#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}
#else // #ifndef LUA_PACK_VALUE
#define LRO_NUMVAL(v) {.value.n = v}
#ifdef ELUA_ENDIAN_LITTLE
#define LRO_FUNCVAL(v) {{(int)v, add_sig(LUA_TLIGHTFUNCTION)}}
#define LRO_LUDATA(v) {{(int)v, add_sig(LUA_TLIGHTUSERDATA)}}
#define LRO_ROVAL(v) {{(int)v, add_sig(LUA_TROTABLE)}}
#define LRO_NILVAL {{0, add_sig(LUA_TNIL)}}
#else // #ifdef ELUA_ENDIAN_LITTLE
#define LRO_FUNCVAL(v) {{add_sig(LUA_TLIGHTFUNCTION), (int)v}}
#define LRO_LUDATA(v) {{add_sig(LUA_TLIGHTUSERDATA), (int)v}}
#define LRO_ROVAL(v) {{add_sig(LUA_TROTABLE), (int)v}}
#define LRO_NILVAL {{add_sig(LUA_TNIL), 0}}
#endif // #ifdef ELUA_ENDIAN_LITTLE
#endif // #ifndef LUA_PACK_VALUE
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
......
......@@ -13,6 +13,7 @@
#include "ldebug.h"
#include "ldo.h"
#include "lflash.h"
#include "lfunc.h"
#include "lgc.h"
#include "llex.h"
......@@ -72,9 +73,12 @@ static void f_luaopen (lua_State *L, void *ud) {
sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
luaN_init(L); /* optionally map RO string table */
#endif
luaT_init(L);
luaX_init(L);
luaS_fix(luaS_newliteral(L, MEMERRMSG));
stringfix(luaS_newliteral(L, MEMERRMSG));
g->GCthreshold = 4*g->totalbytes;
}
......@@ -191,6 +195,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->memlimit = EGC_INITIAL_MEMLIMIT;
#else
g->memlimit = 0;
#endif
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
g->ROstrt.size = 0;
g->ROstrt.nuse = 0;
g->ROstrt.hash = NULL;
g->ROpvmain = NULL;
#endif
for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
......
......@@ -94,6 +94,10 @@ typedef struct global_State {
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
stringtable ROstrt; /* Flash-based hash table for RO strings */
Proto *ROpvmain; /* Flash-based Proto main */
#endif
} global_State;
......
......@@ -61,7 +61,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t 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, readonly ? sizeof(char**)+sizeof(TString) : (l+1)*sizeof(char)+sizeof(TString)));
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (readonly ? sizeof(char**) : (l+1)*sizeof(char))));
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L));
......@@ -71,7 +71,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else {
*(char **)(ts+1) = (char *)str;
luaS_readonly(ts);
l_setbit((ts)->tsv.marked, READONLYBIT);
}
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */
......@@ -80,14 +80,32 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts;
}
#ifdef LUA_CROSS_COMPILER
#define IN_RO_AREA(p) (0)
#else /* xtensa tool chain for ESP */
extern char _irom0_text_start[];
extern char _irom0_text_end[];
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
#endif
int lua_is_ptr_in_ro_area(const char *p) {
return IN_RO_AREA(p);
}
/*
* 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
* This creates miminal savings and prevents the use of LFS based strings
*/
static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, int readonly) {
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
size_t l1;
for (l1=l; l1>=step; l1-=step) /* compute hash */
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o != NULL;
o = o->gch.next) {
......@@ -98,35 +116,27 @@ static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, in
return ts;
}
}
return newlstr(L, str, l, h, readonly); /* not found */
}
static int lua_is_ptr_in_ro_area(const char *p) {
#ifdef LUA_CROSS_COMPILER
return 0;
#else
#include "compiler.h"
return p >= RODATA_START_ADDRESS && p <= RODATA_END_ADDRESS;
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
/*
* The RAM strt is searched first since RAM access is faster tham Flash access.
* If a miss, then search the RO string table.
*/
if (G(L)->ROstrt.hash) {
for (o = G(L)->ROstrt.hash[lmod(h, G(L)->ROstrt.size)];
o != NULL;
o = o->gch.next) {
TString *ts = rawgco2ts(o);
if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
return ts;
}
}
}
#endif
}
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
// If the pointer is in a read-only memory and the string is at least 4 chars in length,
// create it as a read-only string instead
if(lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) && l == c_strlen(str))
return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING);
else
return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING);
}
LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l) {
if(l+1 > sizeof(char**) && l == c_strlen(str))
return luaS_newlstr_helper(L, str, l, LUAS_READONLY_STRING);
else // no point in creating a RO string, as it would actually be larger
return luaS_newlstr_helper(L, str, l, LUAS_REGULAR_STRING);
/* 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 == c_strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING);
return newlstr(L, str, l, h, readonly); /* not found */
}
......
......@@ -13,22 +13,16 @@
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+(luaS_isreadonly(s) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizestring(s) (sizeof(union TString)+(testbit((s)->marked, READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_new(L, s) (luaS_newlstr(L, s, c_strlen(s)))
#define luaS_newro(L, s) (luaS_newrolstr(L, s, c_strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
#define luaS_readonly(s) l_setbit((s)->tsv.marked, READONLYBIT)
#define luaS_isreadonly(s) testbit((s)->marked, READONLYBIT)
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
LUAI_FUNC TString *luaS_newrolstr (lua_State *L, const char *str, size_t l);
#endif
......@@ -445,7 +445,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int oldasize = t->sizearray;
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
resize_hashpart(L, t, nhsize);
if (t->node != dummynode || nhsize>0)
resize_hashpart(L, t, nhsize);
if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
......@@ -749,12 +750,12 @@ int luaH_getn_ro (void *t) {
return len;
}
#if defined(LUA_DEBUG)
int luaH_isdummy (Node *n) { return n == dummynode; }
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key);
}
#endif
int luaH_isdummy (Node *n) { return n == dummynode; }
#endif
......@@ -34,11 +34,9 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
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);
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy (Node *n);
#endif
#endif
......@@ -137,7 +137,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) {
if (!lua_isstring(L, -1))
luaL_error(L, "invalid value (%s) at index %d in table for "
LUA_QL("concat"), luaL_typename(L, -1), i);
luaL_addvalue(b);
luaL_addvalue(b);
}
......
......@@ -14,6 +14,7 @@
#include "lobject.h"
#include "lstate.h"
#include "lgc.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
......@@ -39,7 +40,7 @@ void luaT_init (lua_State *L) {
int i;
for (i=0; i<TM_N; i++) {
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
luaS_fix(G(L)->tmname[i]); /* never collect these names */
stringfix(G(L)->tmname[i]); /* never collect these names */
}
}
......
......@@ -13,6 +13,7 @@
#include "user_version.h"
#include "driver/readline.h"
#include "driver/uart.h"
#include "platform.h"
#define lua_c
......@@ -21,54 +22,16 @@
#include "lauxlib.h"
#include "lualib.h"
#include "legc.h"
#ifdef LUA_FLASH_STORE
#include "lflash.h"
#endif
#include "os_type.h"
lua_State *globalL = NULL;
lua_Load gLoad;
static lua_Load gLoad;
static const char *progname = LUA_PROGNAME;
#if 0
static void lstop (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
static void laction (int i) {
// signal(i, SIG_DFL);
/* if another SIGINT happens before lstop,
terminate process (default action) */
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void print_usage (void) {
#if defined(LUA_USE_STDIO)
c_fprintf(c_stderr,
#else
luai_writestringerror(
#endif
"usage: %s [options] [script [args]].\n"
"Available options are:\n"
" -e stat execute string " LUA_QL("stat") "\n"
" -l name require library " LUA_QL("name") "\n"
" -m limit set memory limit. (units are in Kbytes)\n"
" -i enter interactive mode after executing " LUA_QL("script") "\n"
" -v show version information\n"
" -- stop handling options\n"
" - execute stdin and stop handling options\n"
,
progname);
#if defined(LUA_USE_STDIO)
c_fflush(c_stderr);
#endif
}
#endif
static void l_message (const char *pname, const char *msg) {
#if defined(LUA_USE_STDIO)
if (pname) c_fprintf(c_stderr, "%s: ", pname);
......@@ -154,17 +117,11 @@ static int getargs (lua_State *L, char **argv, int n) {
return narg;
}
#if 0
static int dofile (lua_State *L, const char *name) {
int status = luaL_loadfile(L, name) || docall(L, 0, 1);
return report(L, status);
}
#else
static int dofsfile (lua_State *L, const char *name) {
int status = luaL_loadfsfile(L, name) || docall(L, 0, 1);
return report(L, status);
}
#endif
static int dostring (lua_State *L, const char *s, const char *name) {
int status = luaL_loadbuffer(L, s, c_strlen(s), name) || docall(L, 0, 1);
......@@ -201,92 +158,6 @@ static int incomplete (lua_State *L, int status) {
return 0; /* else... */
}
#if 0
static int pushline (lua_State *L, int firstline) {
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
if (lua_readline(L, b, prmt) == 0)
return 0; /* no input */
l = c_strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[l-1] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* first line starts with `=' ? */
lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
else
lua_pushstring(L, b);
lua_freeline(L, b);
return 1;
}
static int loadline (lua_State *L) {
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
for (;;) { /* repeat until gets a complete line */
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
if (!incomplete(L, status)) break; /* cannot try to add lines? */
if (!pushline(L, 0)) /* no more input? */
return -1;
lua_pushliteral(L, "\n"); /* add a new line... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
}
lua_saveline(L, 1);
lua_remove(L, 1); /* remove line */
return status;
}
static void dotty (lua_State *L) {
int status;
const char *oldprogname = progname;
progname = NULL;
while ((status = loadline(L)) != -1) {
if (status == 0) status = docall(L, 0, 0);
report(L, status);
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, lua_pushfstring(L,
"error calling " LUA_QL("print") " (%s)",
lua_tostring(L, -1)));
}
}
lua_settop(L, 0); /* clear stack */
#if defined(LUA_USE_STDIO)
c_fputs("\n", c_stdout);
c_fflush(c_stdout);
#else
luai_writeline();
#endif
progname = oldprogname;
}
static int handle_script (lua_State *L, char **argv, int n) {
int status;
const char *fname;
int narg = getargs(L, argv, n); /* collect arguments */
lua_setglobal(L, "arg");
fname = argv[n];
if (c_strcmp(fname, "-") == 0 && c_strcmp(argv[n-1], "--") != 0)
fname = NULL; /* stdin */
status = luaL_loadfile(L, fname);
lua_insert(L, -(narg+1));
if (status == 0)
status = docall(L, narg, 0);
else
lua_pop(L, narg);
return report(L, status);
}
#endif
/* check that argument has no extra characters at the end */
#define notail(x) {if ((x)[2] != '\0') return -1;}
......@@ -364,17 +235,16 @@ static int runargs (lua_State *L, char **argv, int n) {
}
#ifndef LUA_INIT_STRING
#define LUA_INIT_STRING "@init.lua"
#endif
static int handle_luainit (lua_State *L) {
const char *init = c_getenv(LUA_INIT);
if (init == NULL) return 0; /* status OK */
else if (init[0] == '@')
#if 0
return dofile(L, init+1);
#else
const char *init = LUA_INIT_STRING;
if (init[0] == '@')
return dofsfile(L, init+1);
#endif
else
return dostring(L, init, "=" LUA_INIT);
return dostring(L, init, LUA_INIT);
}
......@@ -397,40 +267,18 @@ static int pmain (lua_State *L) {
lua_gc(L, LUA_GCRESTART, 0);
print_version(L);
s->status = handle_luainit(L);
#if 0
if (s->status != 0) return 0;
#endif
script = collectargs(argv, &has_i, &has_v, &has_e);
if (script < 0) { /* invalid args? */
#if 0
print_usage();
#endif
s->status = 1;
return 0;
}
// if (has_v) print_version();
s->status = runargs(L, argv, (script > 0) ? script : s->argc);
if (s->status != 0) return 0;
#if 0
if (script)
s->status = handle_script(L, argv, script);
if (s->status != 0) return 0;
if (has_i)
dotty(L);
else if (script == 0 && !has_e && !has_v) {
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
#endif
return 0;
}
static void dojob(lua_Load *load);
static bool readline(lua_Load *load);
char line_buffer[LUA_MAXINPUT];
#ifdef LUA_RPC
int main (int argc, char **argv) {
......@@ -439,6 +287,13 @@ int lua_main (int argc, char **argv) {
#endif
int status;
struct Smain s;
#if defined(NODE_DEBUG) && defined(DEVELOPMENT_USE_GDB) && \
defined(DEVELOPMENT_BREAK_ON_STARTUP_PIN) && DEVELOPMENT_BREAK_ON_STARTUP_PIN > 0
platform_gpio_mode( DEVELOPMENT_BREAK_ON_STARTUP_PIN, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP );
lua_assert(platform_gpio_read(DEVELOPMENT_BREAK_ON_STARTUP_PIN)); // Break if pin pulled low
#endif
lua_State *L = lua_open(); /* create state */
if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory");
......@@ -446,30 +301,44 @@ int lua_main (int argc, char **argv) {
}
s.argc = argc;
s.argv = argv;
status = lua_cpcall(L, &pmain, &s);
report(L, status);
gLoad.L = L;
gLoad.firstline = 1;
gLoad.done = 0;
gLoad.line = line_buffer;
gLoad.line = c_malloc(LUA_MAXINPUT);
gLoad.len = LUA_MAXINPUT;
gLoad.line_position = 0;
gLoad.prmt = get_prompt(L, 1);
dojob(&gLoad);
NODE_DBG("Heap size::%d.\n",system_get_free_heap_size());
NODE_DBG("Heap size:%d.\n",system_get_free_heap_size());
legc_set_mode( L, EGC_ALWAYS, 4096 );
// legc_set_mode( L, EGC_ON_MEM_LIMIT, 4096 );
// lua_close(L);
return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
}
int lua_put_line(const char *s, size_t l) {
if (s == NULL || ++l > LUA_MAXINPUT || gLoad.line_position > 0)
return 0;
c_memcpy(gLoad.line, s, l);
gLoad.line[l] = '\0';
gLoad.line_position = l;
gLoad.done = 1;
NODE_DBG("Get command: %s\n", gLoad.line);
return 1;
}
void lua_handle_input (bool force)
{
while (gLoad.L && (force || readline (&gLoad)))
{
while (gLoad.L && (force || readline (&gLoad))) {
NODE_DBG("Handle Input: first=%u, pos=%u, len=%u, actual=%u, line=%s\n", gLoad.firstline,
gLoad.line_position, gLoad.len, c_strlen(gLoad.line), gLoad.line);
dojob (&gLoad);
force = false;
}
......
......@@ -173,7 +173,6 @@ LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushrolstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
......
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