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 @@ ...@@ -79,6 +79,7 @@
#define VALUEWEAKBIT 4 #define VALUEWEAKBIT 4
#define FIXEDBIT 5 #define FIXEDBIT 5
#define SFIXEDBIT 6 #define SFIXEDBIT 6
#define LFSBIT 6
#define READONLYBIT 7 #define READONLYBIT 7
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
...@@ -100,6 +101,13 @@ ...@@ -100,6 +101,13 @@
#define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT) #define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT)
#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT) #define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT)
#define unfixedstack(x) resetbit((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) { \ #define luaC_checkGC(L) { \
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ 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[] = { ...@@ -326,7 +326,7 @@ const LUA_REG_TYPE math_map[] = {
{LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)}, {LSTRKEY("randomseed"), LFUNCVAL(math_randomseed)},
{LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)}, {LSTRKEY("sqrt"), LFUNCVAL(math_sqrt)},
#if LUA_OPTIMIZE_MEMORY > 0 #if LUA_OPTIMIZE_MEMORY > 0
{LSTRKEY("huge"), LNUMVAL(LONG_MAX)}, {LSTRKEY("huge"), LNUMVAL(INT_MAX)},
#endif #endif
#else #else
{LSTRKEY("abs"), LFUNCVAL(math_abs)}, {LSTRKEY("abs"), LFUNCVAL(math_abs)},
...@@ -374,7 +374,7 @@ const LUA_REG_TYPE math_map[] = { ...@@ -374,7 +374,7 @@ const LUA_REG_TYPE math_map[] = {
*/ */
#if defined LUA_NUMBER_INTEGRAL #if defined LUA_NUMBER_INTEGRAL
# include "c_limits.h" /* for LONG_MAX */ # include "c_limits.h" /* for INT_MAX */
#endif #endif
LUALIB_API int luaopen_math (lua_State *L) { LUALIB_API int luaopen_math (lua_State *L) {
...@@ -383,7 +383,7 @@ LUALIB_API int luaopen_math (lua_State *L) { ...@@ -383,7 +383,7 @@ LUALIB_API int luaopen_math (lua_State *L) {
#else #else
luaL_register(L, LUA_MATHLIBNAME, math_map); luaL_register(L, LUA_MATHLIBNAME, math_map);
# if defined LUA_NUMBER_INTEGRAL # if defined LUA_NUMBER_INTEGRAL
lua_pushnumber(L, LONG_MAX); lua_pushnumber(L, INT_MAX);
lua_setfield(L, -2, "huge"); lua_setfield(L, -2, "huge");
# else # else
lua_pushnumber(L, PI); lua_pushnumber(L, PI);
......
...@@ -613,7 +613,7 @@ static int ll_seeall (lua_State *L) { ...@@ -613,7 +613,7 @@ static int ll_seeall (lua_State *L) {
static void setpath (lua_State *L, const char *fieldname, const char *envname, static void setpath (lua_State *L, const char *fieldname, const char *envname,
const char *def) { 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? */ if (path == NULL) /* no environment variable? */
lua_pushstring(L, def); /* use default */ lua_pushstring(L, def); /* use default */
else { else {
......
...@@ -53,7 +53,8 @@ int luaO_fb2int (int x) { ...@@ -53,7 +53,8 @@ int luaO_fb2int (int x) {
int luaO_log2 (unsigned 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, 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, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
...@@ -65,10 +66,12 @@ int luaO_log2 (unsigned int x) { ...@@ -65,10 +66,12 @@ int luaO_log2 (unsigned int x) {
}; };
int l = -1; int l = -1;
while (x >= 256) { l += 8; x >>= 8; } while (x >= 256) { l += 8; x >>= 8; }
#ifdef LUA_CROSS_COMPILER
return l + log_2[x]; return l + log_2[x];
#else #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 #endif
} }
...@@ -103,7 +106,7 @@ int luaO_str2d (const char *s, lua_Number *result) { ...@@ -103,7 +106,7 @@ int luaO_str2d (const char *s, lua_Number *result) {
#if defined(LUA_CROSS_COMPILER) #if defined(LUA_CROSS_COMPILER)
{ {
long lres = strtoul(s, &endptr, 16); long lres = strtoul(s, &endptr, 16);
#if LONG_MAX != 2147483647L #if INT_MAX != 2147483647L
if (lres & ~0xffffffffL) if (lres & ~0xffffffffL)
*result = cast_num(-1); *result = cast_num(-1);
else if (lres & 0x80000000L) else if (lres & 0x80000000L)
......
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
#define NUM_TAGS (LAST_TAG+1) #define NUM_TAGS (LAST_TAG+1)
/* mask for 'read-only' objects. must match READONLYBIT in lgc.h' */ #define READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */
#define READONLYMASK 128 #ifdef LUA_FLASH_STORE
#define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */
#endif
/* /*
** Extra tags for non-values ** Extra tags for non-values
*/ */
...@@ -55,86 +55,39 @@ typedef struct GCheader { ...@@ -55,86 +55,39 @@ typedef struct GCheader {
CommonHeader; CommonHeader;
} GCheader; } 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 ** 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 { typedef union {
GCObject *gc; GCObject *gc;
void *p; void *p;
lua_Number n; lua_Number n;
int b; int b;
} Value; } Value;
#endif // #if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
/* /*
** Tagged Values ** Tagged Values
*/ */
#ifndef LUA_PACK_VALUE
#define TValuefields Value value; int tt #define TValuefields Value value; int tt
#define LUA_TVALUE_NIL {NULL}, LUA_TNIL #define LUA_TVALUE_NIL {NULL}, LUA_TNIL
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack(4)
#endif
typedef struct lua_TValue { typedef struct lua_TValue {
TValuefields; TValuefields;
} TValue; } TValue;
#else // #ifndef LUA_PACK_VALUE #if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#ifdef ELUA_ENDIAN_LITTLE #pragma pack()
#define TValuefields union { \ #endif
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
/* Macros to test type */ /* Macros to test type */
#ifndef LUA_PACK_VALUE
#define ttisnil(o) (ttype(o) == LUA_TNIL) #define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) #define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING) #define ttisstring(o) (ttype(o) == LUA_TSTRING)
...@@ -146,27 +99,11 @@ typedef TValuefields TValue; ...@@ -146,27 +99,11 @@ typedef TValuefields TValue;
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) #define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
#define ttisrotable(o) (ttype(o) == LUA_TROTABLE) #define ttisrotable(o) (ttype(o) == LUA_TROTABLE)
#define ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION) #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 */ /* Macros to access values */
#ifndef LUA_PACK_VALUE
#define ttype(o) ((o)->tt) #define ttype(o) ((void) (o)->value, (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 gcvalue(o) check_exp(iscollectable(o), (o)->value.gc) #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p) #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
#define rvalue(o) check_exp(ttisrotable(o), (o)->value.p) #define rvalue(o) check_exp(ttisrotable(o), (o)->value.p)
...@@ -186,24 +123,15 @@ typedef TValuefields TValue; ...@@ -186,24 +123,15 @@ typedef TValuefields TValue;
/* /*
** for internal debug only ** for internal debug only
*/ */
#ifndef LUA_PACK_VALUE
#define checkconsistency(obj) \ #define checkconsistency(obj) \
lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt)) lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
#define checkliveness(g,obj) \ #define checkliveness(g,obj) \
lua_assert(!iscollectable(obj) || \ lua_assert(!iscollectable(obj) || \
((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc))) ((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 */ /* Macros to set values */
#ifndef LUA_PACK_VALUE
#define setnilvalue(obj) ((obj)->tt=LUA_TNIL) #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
#define setnvalue(obj,x) \ #define setnvalue(obj,x) \
...@@ -257,69 +185,10 @@ typedef TValuefields TValue; ...@@ -257,69 +185,10 @@ typedef TValuefields TValue;
i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \ i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \
checkliveness(G(L),i_o); } checkliveness(G(L),i_o); }
#define setobj(L,obj1,obj2) \ #define setobj(L,obj1,obj2) \
{ const TValue *o2=(obj2); TValue *o1=(obj1); \ { const TValue *o2=(obj2); TValue *o1=(obj1); \
o1->value = o2->value; o1->tt=o2->tt; \ o1->value = o2->value; o1->tt=o2->tt; \
checkliveness(G(L),o1); } 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 ** different types of sets, according to destination
...@@ -340,13 +209,7 @@ typedef TValuefields TValue; ...@@ -340,13 +209,7 @@ typedef TValuefields TValue;
#define setobj2n setobj #define setobj2n setobj
#define setsvalue2n setsvalue #define setsvalue2n setsvalue
#ifndef LUA_PACK_VALUE #define setttype(obj, stt) ((void) (obj)->value, (obj)->tt = (stt))
#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 iscollectable(o) (ttype(o) >= LUA_TSTRING) #define iscollectable(o) (ttype(o) >= LUA_TSTRING)
...@@ -367,9 +230,16 @@ typedef union TString { ...@@ -367,9 +230,16 @@ typedef union TString {
} tsv; } tsv;
} TString; } TString;
#ifdef LUA_CROSS_COMPILER
#define getstr(ts) (((ts)->tsv.marked & READONLYMASK) ? cast(const char *, *(const char**)((ts) + 1)) : cast(const char *, (ts) + 1)) #define isreadonly(o) (0)
#define svalue(o) getstr(rawtsvalue(o)) #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 { ...@@ -418,6 +288,7 @@ typedef struct Proto {
lu_byte is_vararg; lu_byte is_vararg;
lu_byte maxstacksize; lu_byte maxstacksize;
} Proto; } Proto;
#define proto_isreadonly(p) isreadonly(*(p))
/* masks for new-style vararg */ /* masks for new-style vararg */
...@@ -487,7 +358,6 @@ typedef union Closure { ...@@ -487,7 +358,6 @@ typedef union Closure {
** Tables ** Tables
*/ */
#ifndef LUA_PACK_VALUE
typedef union TKey { typedef union TKey {
struct { struct {
TValuefields; TValuefields;
...@@ -497,16 +367,6 @@ typedef union TKey { ...@@ -497,16 +367,6 @@ typedef union TKey {
} TKey; } TKey;
#define LUA_TKEY_NIL {LUA_TVALUE_NIL, NULL} #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 { typedef struct Node {
TValue i_val; TValue i_val;
......
...@@ -916,12 +916,11 @@ static int block_follow (int token) { ...@@ -916,12 +916,11 @@ static int block_follow (int token) {
static void block (LexState *ls) { static void block (LexState *ls) {
/* block -> chunk */ /* block -> chunk */
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt)); BlockCnt bl;
enterblock(fs, pbl, 0); enterblock(fs, &bl, 0);
chunk(ls); chunk(ls);
lua_assert(pbl->breaklist == NO_JUMP); lua_assert(bl.breaklist == NO_JUMP);
leaveblock(fs); leaveblock(fs);
luaM_free(ls->L,pbl);
} }
...@@ -1081,13 +1080,13 @@ static int exp1 (LexState *ls) { ...@@ -1081,13 +1080,13 @@ static int exp1 (LexState *ls) {
static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
/* forbody -> DO block */ /* forbody -> DO block */
BlockCnt *pbl = (BlockCnt*)luaM_malloc(ls->L,sizeof(BlockCnt)); BlockCnt bl;
FuncState *fs = ls->fs; FuncState *fs = ls->fs;
int prep, endfor; int prep, endfor;
adjustlocalvars(ls, 3); /* control variables */ adjustlocalvars(ls, 3); /* control variables */
checknext(ls, TK_DO); checknext(ls, TK_DO);
prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); 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); adjustlocalvars(ls, nvars);
luaK_reserveregs(fs, nvars); luaK_reserveregs(fs, nvars);
block(ls); block(ls);
...@@ -1097,7 +1096,6 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { ...@@ -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_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */ luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1); luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
luaM_free(ls->L,pbl);
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#undef LNILVAL #undef LNILVAL
#undef LREGISTER #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 LUA_REG_TYPE luaR_entry
#define LSTRKEY LRO_STRKEY #define LSTRKEY LRO_STRKEY
#define LNUMKEY LRO_NUMKEY #define LNUMKEY LRO_NUMKEY
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#define LUAR_FINDVALUE 1 #define LUAR_FINDVALUE 1
/* Externally defined read-only table array */ /* 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 */ /* Find a global "read only table" in the constant lua_rotable array */
void* luaR_findglobal(const char *name, unsigned len) { 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, ...@@ -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) { if (pentries[pos].key.type != LUA_TNIL) {
/* Found an entry */ /* Found an entry */
if (pentries[pos].key.type == LUA_TSTRING) 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 else
setnvalue(key, (lua_Number)pentries[pos].key.id.numkey) setnvalue(key, (lua_Number)pentries[pos].key.id.numkey)
setobj2s(L, val, &pentries[pos].value); setobj2s(L, val, &pentries[pos].value);
...@@ -125,12 +125,22 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) { ...@@ -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
#ifdef LUA_META_ROTABLES /* Set in RO check depending on platform */
#if defined(LUA_CROSS_COMPILER) && defined(__CYGWIN__)
#include "compiler.h" 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) { int luaR_isrotable(void *p) {
return RODATA_START_ADDRESS <= (char*)p && (char*)p <= RODATA_END_ADDRESS; return IN_RO_AREA((char *)p);
} }
#endif #endif
...@@ -4,32 +4,16 @@ ...@@ -4,32 +4,16 @@
#define lrotable_h #define lrotable_h
#include "lua.h" #include "lua.h"
#include "llimits.h"
#include "lobject.h"
#include "luaconf.h" #include "luaconf.h"
#include "lobject.h"
#include "llimits.h"
/* Macros one can use to define rotable entries */ /* Macros one can use to define rotable entries */
#ifndef LUA_PACK_VALUE
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION} #define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_LUDATA(v) {{.p = v}, LUA_TLIGHTUSERDATA} #define LRO_LUDATA(v) {{.p = v}, LUA_TLIGHTUSERDATA}
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER} #define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE} #define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL} #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_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}} #define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}} #define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "ldebug.h" #include "ldebug.h"
#include "ldo.h" #include "ldo.h"
#include "lflash.h"
#include "lfunc.h" #include "lfunc.h"
#include "lgc.h" #include "lgc.h"
#include "llex.h" #include "llex.h"
...@@ -72,9 +73,12 @@ static void f_luaopen (lua_State *L, void *ud) { ...@@ -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, gt(L), luaH_new(L, 0, 2)); /* table of globals */
sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */ sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ 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); luaT_init(L);
luaX_init(L); luaX_init(L);
luaS_fix(luaS_newliteral(L, MEMERRMSG)); stringfix(luaS_newliteral(L, MEMERRMSG));
g->GCthreshold = 4*g->totalbytes; g->GCthreshold = 4*g->totalbytes;
} }
...@@ -191,6 +195,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { ...@@ -191,6 +195,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->memlimit = EGC_INITIAL_MEMLIMIT; g->memlimit = EGC_INITIAL_MEMLIMIT;
#else #else
g->memlimit = 0; 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 #endif
for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
......
...@@ -94,6 +94,10 @@ typedef struct global_State { ...@@ -94,6 +94,10 @@ typedef struct global_State {
UpVal uvhead; /* head of double-linked list of all open upvalues */ UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */ struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */ 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; } global_State;
......
...@@ -61,7 +61,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, ...@@ -61,7 +61,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
tb = &G(L)->strt; tb = &G(L)->strt;
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */ 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.len = l;
ts->tsv.hash = h; ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L)); ts->tsv.marked = luaC_white(G(L));
...@@ -71,7 +71,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, ...@@ -71,7 +71,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
((char *)(ts+1))[l] = '\0'; /* ending 0 */ ((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else { } else {
*(char **)(ts+1) = (char *)str; *(char **)(ts+1) = (char *)str;
luaS_readonly(ts); l_setbit((ts)->tsv.marked, READONLYBIT);
} }
h = lmod(h, tb->size); h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */ 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, ...@@ -80,14 +80,32 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts; 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; GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */ 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 step = (l>>5)+1; /* if string is too long, don't hash all its chars */
size_t l1; size_t l1;
for (l1=l; l1>=step; l1-=step) /* compute hash */ for (l1=l; l1>=step; l1-=step) /* compute hash */
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o != NULL; o != NULL;
o = o->gch.next) { o = o->gch.next) {
...@@ -98,35 +116,27 @@ static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, in ...@@ -98,35 +116,27 @@ static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, in
return ts; return ts;
} }
} }
return newlstr(L, str, l, h, readonly); /* not found */ #if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
} /*
* The RAM strt is searched first since RAM access is faster tham Flash access.
static int lua_is_ptr_in_ro_area(const char *p) { * If a miss, then search the RO string table.
#ifdef LUA_CROSS_COMPILER */
return 0; if (G(L)->ROstrt.hash) {
#else for (o = G(L)->ROstrt.hash[lmod(h, G(L)->ROstrt.size)];
o != NULL;
#include "compiler.h" o = o->gch.next) {
TString *ts = rawgco2ts(o);
return p >= RODATA_START_ADDRESS && p <= RODATA_END_ADDRESS; if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
return ts;
}
}
}
#endif #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) */
TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { int readonly = (lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) &&
// If the pointer is in a read-only memory and the string is at least 4 chars in length, l == c_strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING);
// create it as a read-only string instead return newlstr(L, str, l, h, readonly); /* not found */
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);
} }
......
...@@ -13,22 +13,16 @@ ...@@ -13,22 +13,16 @@
#include "lstate.h" #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 sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_new(L, s) (luaS_newlstr(L, s, c_strlen(s))) #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, \ #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1)) (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 void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 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_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 #endif
...@@ -445,7 +445,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { ...@@ -445,7 +445,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int oldasize = t->sizearray; int oldasize = t->sizearray;
if (nasize > oldasize) /* array part must grow? */ if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize); setarrayvector(L, t, nasize);
resize_hashpart(L, t, nhsize); if (t->node != dummynode || nhsize>0)
resize_hashpart(L, t, nhsize);
if (nasize < oldasize) { /* array part must shrink? */ if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize; t->sizearray = nasize;
/* re-insert elements from vanishing slice */ /* re-insert elements from vanishing slice */
...@@ -749,12 +750,12 @@ int luaH_getn_ro (void *t) { ...@@ -749,12 +750,12 @@ int luaH_getn_ro (void *t) {
return len; return len;
} }
#if defined(LUA_DEBUG) int luaH_isdummy (Node *n) { return n == dummynode; }
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) { Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key); return mainposition(t, key);
} }
#endif
int luaH_isdummy (Node *n) { return n == dummynode; }
#endif
...@@ -34,11 +34,9 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); ...@@ -34,11 +34,9 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_next_ro (lua_State *L, void *t, StkId key); LUAI_FUNC int luaH_next_ro (lua_State *L, void *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t); LUAI_FUNC int luaH_getn (Table *t);
LUAI_FUNC int luaH_getn_ro (void *t); LUAI_FUNC int luaH_getn_ro (void *t);
LUAI_FUNC int luaH_isdummy (Node *n);
#if defined(LUA_DEBUG) #if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy (Node *n);
#endif #endif
#endif #endif
...@@ -137,7 +137,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) { ...@@ -137,7 +137,7 @@ static void addfield (lua_State *L, luaL_Buffer *b, int i) {
if (!lua_isstring(L, -1)) if (!lua_isstring(L, -1))
luaL_error(L, "invalid value (%s) at index %d in table for " luaL_error(L, "invalid value (%s) at index %d in table for "
LUA_QL("concat"), luaL_typename(L, -1), i); LUA_QL("concat"), luaL_typename(L, -1), i);
luaL_addvalue(b); luaL_addvalue(b);
} }
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
#include "lgc.h"
#include "lstring.h" #include "lstring.h"
#include "ltable.h" #include "ltable.h"
#include "ltm.h" #include "ltm.h"
...@@ -39,7 +40,7 @@ void luaT_init (lua_State *L) { ...@@ -39,7 +40,7 @@ void luaT_init (lua_State *L) {
int i; int i;
for (i=0; i<TM_N; i++) { for (i=0; i<TM_N; i++) {
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
luaS_fix(G(L)->tmname[i]); /* never collect these names */ stringfix(G(L)->tmname[i]); /* never collect these names */
} }
} }
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "user_version.h" #include "user_version.h"
#include "driver/readline.h" #include "driver/readline.h"
#include "driver/uart.h" #include "driver/uart.h"
#include "platform.h"
#define lua_c #define lua_c
...@@ -21,54 +22,16 @@ ...@@ -21,54 +22,16 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
#include "legc.h" #include "legc.h"
#ifdef LUA_FLASH_STORE
#include "lflash.h"
#endif
#include "os_type.h" #include "os_type.h"
lua_State *globalL = NULL; lua_State *globalL = NULL;
lua_Load gLoad; static lua_Load gLoad;
static const char *progname = LUA_PROGNAME; static const char *progname = LUA_PROGNAME;
#if 0
static void lstop (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
static void laction (int i) {
// signal(i, SIG_DFL);
/* if another SIGINT happens before lstop,
terminate process (default action) */
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void print_usage (void) {
#if defined(LUA_USE_STDIO)
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) { static void l_message (const char *pname, const char *msg) {
#if defined(LUA_USE_STDIO) #if defined(LUA_USE_STDIO)
if (pname) c_fprintf(c_stderr, "%s: ", pname); if (pname) c_fprintf(c_stderr, "%s: ", pname);
...@@ -154,17 +117,11 @@ static int getargs (lua_State *L, char **argv, int n) { ...@@ -154,17 +117,11 @@ static int getargs (lua_State *L, char **argv, int n) {
return narg; 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) { static int dofsfile (lua_State *L, const char *name) {
int status = luaL_loadfsfile(L, name) || docall(L, 0, 1); int status = luaL_loadfsfile(L, name) || docall(L, 0, 1);
return report(L, status); return report(L, status);
} }
#endif
static int dostring (lua_State *L, const char *s, const char *name) { static int dostring (lua_State *L, const char *s, const char *name) {
int status = luaL_loadbuffer(L, s, c_strlen(s), name) || docall(L, 0, 1); 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) { ...@@ -201,92 +158,6 @@ static int incomplete (lua_State *L, int status) {
return 0; /* else... */ return 0; /* else... */
} }
#if 0
static int pushline (lua_State *L, int firstline) {
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
if (lua_readline(L, b, prmt) == 0)
return 0; /* no input */
l = 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 */ /* check that argument has no extra characters at the end */
#define notail(x) {if ((x)[2] != '\0') return -1;} #define notail(x) {if ((x)[2] != '\0') return -1;}
...@@ -364,17 +235,16 @@ static int runargs (lua_State *L, char **argv, int n) { ...@@ -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) { static int handle_luainit (lua_State *L) {
const char *init = c_getenv(LUA_INIT); const char *init = LUA_INIT_STRING;
if (init == NULL) return 0; /* status OK */ if (init[0] == '@')
else if (init[0] == '@')
#if 0
return dofile(L, init+1);
#else
return dofsfile(L, init+1); return dofsfile(L, init+1);
#endif
else else
return dostring(L, init, "=" LUA_INIT); return dostring(L, init, LUA_INIT);
} }
...@@ -397,40 +267,18 @@ static int pmain (lua_State *L) { ...@@ -397,40 +267,18 @@ static int pmain (lua_State *L) {
lua_gc(L, LUA_GCRESTART, 0); lua_gc(L, LUA_GCRESTART, 0);
print_version(L); print_version(L);
s->status = handle_luainit(L); s->status = handle_luainit(L);
#if 0
if (s->status != 0) return 0;
#endif
script = collectargs(argv, &has_i, &has_v, &has_e); script = collectargs(argv, &has_i, &has_v, &has_e);
if (script < 0) { /* invalid args? */ if (script < 0) { /* invalid args? */
#if 0
print_usage();
#endif
s->status = 1; s->status = 1;
return 0; return 0;
} }
// if (has_v) print_version();
s->status = runargs(L, argv, (script > 0) ? script : s->argc); s->status = runargs(L, argv, (script > 0) ? script : s->argc);
if (s->status != 0) return 0; if (s->status != 0) return 0;
#if 0
if (script)
s->status = handle_script(L, argv, script);
if (s->status != 0) return 0;
if (has_i)
dotty(L);
else if (script == 0 && !has_e && !has_v) {
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
#endif
return 0; return 0;
} }
static void dojob(lua_Load *load); static void dojob(lua_Load *load);
static bool readline(lua_Load *load); static bool readline(lua_Load *load);
char line_buffer[LUA_MAXINPUT];
#ifdef LUA_RPC #ifdef LUA_RPC
int main (int argc, char **argv) { int main (int argc, char **argv) {
...@@ -439,6 +287,13 @@ int lua_main (int argc, char **argv) { ...@@ -439,6 +287,13 @@ int lua_main (int argc, char **argv) {
#endif #endif
int status; int status;
struct Smain s; 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 */ lua_State *L = lua_open(); /* create state */
if (L == NULL) { if (L == NULL) {
l_message(argv[0], "cannot create state: not enough memory"); l_message(argv[0], "cannot create state: not enough memory");
...@@ -446,30 +301,44 @@ int lua_main (int argc, char **argv) { ...@@ -446,30 +301,44 @@ int lua_main (int argc, char **argv) {
} }
s.argc = argc; s.argc = argc;
s.argv = argv; s.argv = argv;
status = lua_cpcall(L, &pmain, &s); status = lua_cpcall(L, &pmain, &s);
report(L, status); report(L, status);
gLoad.L = L; gLoad.L = L;
gLoad.firstline = 1; gLoad.firstline = 1;
gLoad.done = 0; gLoad.done = 0;
gLoad.line = line_buffer; gLoad.line = c_malloc(LUA_MAXINPUT);
gLoad.len = LUA_MAXINPUT; gLoad.len = LUA_MAXINPUT;
gLoad.line_position = 0; gLoad.line_position = 0;
gLoad.prmt = get_prompt(L, 1); gLoad.prmt = get_prompt(L, 1);
dojob(&gLoad); dojob(&gLoad);
NODE_DBG("Heap size::%d.\n",system_get_free_heap_size()); NODE_DBG("Heap size:%d.\n",system_get_free_heap_size());
legc_set_mode( L, EGC_ALWAYS, 4096 ); legc_set_mode( L, EGC_ALWAYS, 4096 );
// legc_set_mode( L, EGC_ON_MEM_LIMIT, 4096 ); // legc_set_mode( L, EGC_ON_MEM_LIMIT, 4096 );
// lua_close(L); // lua_close(L);
return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS;
} }
int lua_put_line(const char *s, size_t l) {
if (s == NULL || ++l > LUA_MAXINPUT || gLoad.line_position > 0)
return 0;
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) 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); dojob (&gLoad);
force = false; force = false;
} }
......
...@@ -173,7 +173,6 @@ LUA_API void (lua_pushnil) (lua_State *L); ...@@ -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_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l); LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushrolstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushstring) (lua_State *L, const char *s); LUA_API void (lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp); va_list argp);
......
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