Commit 4ae52c23 authored by TerryE's avatar TerryE
Browse files

Alpha working wersion for third party evaluation

parent e00d927a
/*
** $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);
......
...@@ -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 32 - 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,33 @@ typedef struct GCheader { ...@@ -55,86 +55,33 @@ 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
typedef struct lua_TValue { typedef struct lua_TValue {
TValuefields; TValuefields;
} TValue; } 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
/* 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 +93,11 @@ typedef TValuefields TValue; ...@@ -146,27 +93,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 +117,15 @@ typedef TValuefields TValue; ...@@ -186,24 +117,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 +179,10 @@ typedef TValuefields TValue; ...@@ -257,69 +179,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 +203,7 @@ typedef TValuefields TValue; ...@@ -340,13 +203,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,8 +224,15 @@ typedef union TString { ...@@ -367,8 +224,15 @@ 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)
#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)) #define svalue(o) getstr(rawtsvalue(o))
...@@ -418,6 +282,7 @@ typedef struct Proto { ...@@ -418,6 +282,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 +352,6 @@ typedef union Closure { ...@@ -487,7 +352,6 @@ typedef union Closure {
** Tables ** Tables
*/ */
#ifndef LUA_PACK_VALUE
typedef union TKey { typedef union TKey {
struct { struct {
TValuefields; TValuefields;
...@@ -497,16 +361,6 @@ typedef union TKey { ...@@ -497,16 +361,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;
......
...@@ -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,11 +14,10 @@ ...@@ -14,11 +14,10 @@
#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) {
#ifndef LUA_CROSS_COMPILER
unsigned i; unsigned i;
if (c_strlen(name) > LUA_MAX_ROTABLE_NAME) if (c_strlen(name) > LUA_MAX_ROTABLE_NAME)
...@@ -27,7 +26,6 @@ void* luaR_findglobal(const char *name, unsigned len) { ...@@ -27,7 +26,6 @@ void* luaR_findglobal(const char *name, unsigned len) {
if (*lua_rotable[i].name != '\0' && c_strlen(lua_rotable[i].name) == len && !c_strncmp(lua_rotable[i].name, name, len)) { if (*lua_rotable[i].name != '\0' && c_strlen(lua_rotable[i].name) == len && !c_strncmp(lua_rotable[i].name, name, len)) {
return (void*)(lua_rotable[i].pentries); return (void*)(lua_rotable[i].pentries);
} }
#endif
return NULL; return NULL;
} }
...@@ -87,7 +85,7 @@ static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos, ...@@ -87,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);
...@@ -129,10 +127,15 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) { ...@@ -129,10 +127,15 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) {
/* Return 1 if the given pointer is a rotable */ /* Return 1 if the given pointer is a rotable */
#ifdef LUA_META_ROTABLES #ifdef LUA_META_ROTABLES
#ifdef LUA_CROSS_COMPILER
extern char edata[];
int luaR_isrotable(void *p) {
return (char*)p <= edata;
}
#else
#include "compiler.h" #include "compiler.h"
int luaR_isrotable(void *p) { int luaR_isrotable(void *p) {
return RODATA_START_ADDRESS <= (char*)p && (char*)p <= RODATA_END_ADDRESS; return RODATA_START_ADDRESS <= (char*)p && (char*)p <= RODATA_END_ADDRESS;
} }
#endif #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,29 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, ...@@ -80,14 +80,29 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts; return ts;
} }
#include "compiler.h"
static int lua_is_ptr_in_ro_area(const char *p) {
#ifdef LUA_CROSS_COMPILER
return 0;
#else
return p >= RODATA_START_ADDRESS && p <= RODATA_END_ADDRESS;
#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
* 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 +113,27 @@ static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, in ...@@ -98,35 +113,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
...@@ -749,12 +749,12 @@ int luaH_getn_ro (void *t) { ...@@ -749,12 +749,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
...@@ -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,7 +22,9 @@ ...@@ -21,7 +22,9 @@
#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;
...@@ -30,44 +33,6 @@ lua_Load gLoad; ...@@ -30,44 +33,6 @@ 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)
...@@ -154,17 +119,11 @@ static int getargs (lua_State *L, char **argv, int n) { ...@@ -154,17 +119,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 +160,6 @@ static int incomplete (lua_State *L, int status) { ...@@ -201,92 +160,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;}
...@@ -368,11 +241,7 @@ static int handle_luainit (lua_State *L) { ...@@ -368,11 +241,7 @@ static int handle_luainit (lua_State *L) {
const char *init = c_getenv(LUA_INIT); const char *init = c_getenv(LUA_INIT);
if (init == NULL) return 0; /* status OK */ if (init == NULL) return 0; /* status OK */
else 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,34 +266,13 @@ static int pmain (lua_State *L) { ...@@ -397,34 +266,13 @@ 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;
} }
...@@ -439,6 +287,12 @@ int lua_main (int argc, char **argv) { ...@@ -439,6 +287,12 @@ 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) && BREAK_ON_STARTUP_PIN > 0
platform_gpio_mode( BREAK_ON_STARTUP_PIN, PLATFORM_GPIO_INPUT, PLATFORM_GPIO_PULLUP );
lua_assert(platform_gpio_read(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,7 +300,9 @@ int lua_main (int argc, char **argv) { ...@@ -446,7 +300,9 @@ 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;
...@@ -468,11 +324,8 @@ int lua_main (int argc, char **argv) { ...@@ -468,11 +324,8 @@ int lua_main (int argc, char **argv) {
void lua_handle_input (bool force) void lua_handle_input (bool force)
{ {
while (gLoad.L && (force || readline (&gLoad))) if (gLoad.L && (force || readline (&gLoad)))
{
dojob (&gLoad); dojob (&gLoad);
force = false;
}
} }
void donejob(lua_Load *load){ void donejob(lua_Load *load){
...@@ -602,12 +455,11 @@ static bool readline(lua_Load *load){ ...@@ -602,12 +455,11 @@ static bool readline(lua_Load *load){
{ {
/* Get a empty line, then go to get a new line */ /* Get a empty line, then go to get a new line */
c_puts(load->prmt); c_puts(load->prmt);
continue;
} else { } else {
load->done = 1; load->done = 1;
need_dojob = true; need_dojob = true;
break;
} }
continue;
} }
/* other control character or not an acsii character */ /* other control character or not an acsii character */
......
...@@ -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);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#define c_freopen freopen #define c_freopen freopen
#define c_getc getc #define c_getc getc
#define c_getenv getenv #define c_getenv getenv
#define c_malloc malloc
#define c_memcmp memcmp #define c_memcmp memcmp
#define c_memcpy memcpy #define c_memcpy memcpy
#define c_printf printf #define c_printf printf
......
...@@ -7,30 +7,29 @@ ...@@ -7,30 +7,29 @@
.NOTPARALLEL: .NOTPARALLEL:
CCFLAGS:= -I.. -I../../include -I../../../include -I ../../libc CCFLAGS:= -I.. -I../../include -I../../../include -I ../../libc
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -Wl,-Map=mapfile
CCFLAGS += -Wall CCFLAGS += -Wall
DEFINES += -DLUA_CROSS_COMPILER DEFINES += -DLUA_CROSS_COMPILER -DLUA_OPTIMIZE_MEMORY=2
TARGET = host TARGET = host
ifeq ($(FLAVOR),release) ifeq ($(FLAVOR),debug)
CCFLAGS += -O0 -g
TARGET_LDFLAGS += -O0 -g
else
FLAVOR = release
CCFLAGS += -O2 CCFLAGS += -O2
TARGET_LDFLAGS += -O2 TARGET_LDFLAGS += -O2
else
FLAVOR = debug
CCFLAGS += -O2 -g
TARGET_LDFLAGS += -O2 -g
endif endif
LUACSRC := luac.c lflashimg.c loslib.c print.c LUACSRC := luac.c lflashimg.c liolib.c loslib.c print.c
LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c \ LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c \
ldebug.c ldo.c ldump.c lfunc.c lgc.c \ ldo.c ldump.c lfunc.c lgc.c linit.c llex.c \
llex.c lmathlib.c lmem.c loadlib.c lobject.c \ lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c lparser.c \
lopcodes.c lparser.c lrotable.c lstate.c lstring.c \ lrotable.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
lstrlib.c ltable.c ltablib.c ltm.c lundump.c \ ltm.c lundump.c lvm.c lzio.c
lvm.c lzio.c
LIBCSRC := c_stdlib.c LIBCSRC := c_stdlib.c
# #
...@@ -83,6 +82,3 @@ $(ODIR)/%.d: %.c ...@@ -83,6 +82,3 @@ $(ODIR)/%.d: %.c
$(CC) -M $(CFLAGS) $< > $@.$$$$; \ $(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\.o\)[ :]*,$(ODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \ sed 's,\($*\.o\)[ :]*,$(ODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$ rm -f $@.$$$$
# echo 's,\($*\.o\)[ :]*,$(ODIR)/\1 $@ : ,g'; \
...@@ -224,7 +224,7 @@ static void createROstrt(lua_State *L, FlashHeader *fh) { ...@@ -224,7 +224,7 @@ static void createROstrt(lua_State *L, FlashHeader *fh) {
toFlashAddr(L, *e, fts); // add reference to TS to lookup vector toFlashAddr(L, *e, fts); // add reference to TS to lookup vector
toFlashAddr(L, fts->next, last); // and chain to previous entry if any toFlashAddr(L, fts->next, last); // and chain to previous entry if any
fts->tt = LUA_TSTRING; // Set as String fts->tt = LUA_TSTRING; // Set as String
fts->marked = bitmask(FIXEDBIT); // Fixed with no Whitebits set fts->marked = bitmask(LFSBIT); // LFS string with no Whitebits set
fts->hash = hash; // add hash fts->hash = hash; // add hash
fts->len = len; // and length fts->len = len; // and length
memcpy(flashAlloc(L, ALIGN(len+1)), p, ALIGN(len+1)); // copy string memcpy(flashAlloc(L, ALIGN(len+1)), p, ALIGN(len+1)); // copy string
...@@ -262,14 +262,21 @@ static void *resolveTString(lua_State* L, TString *s) { ...@@ -262,14 +262,21 @@ static void *resolveTString(lua_State* L, TString *s) {
* src Source of record * src Source of record
* returns Address of destination record * returns Address of destination record
*/ */
#define TARGET_TV_SIZE (2*sizeof(lua_Number))
static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) { static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
/* ToS is the string address mapping table */ /* ToS is the string address mapping table */
if (n == 0) if (n == 0)
return NULL; return NULL;
int i; int i, recsize;
void *newts; void *newts;
// A bit of a botch because fmt is either "V" or a string of WORDSIZE specifiers */ /* A bit of a botch because fmt is either "V" or a string of WORDSIZE specifiers */
int recsize = fmt[0]=='V' ? 16 : WORDSIZE * strlen(fmt); /* The size 8 for integer builds and 16 for float ones on both architectures */
if (fmt[0]=='V') {
lua_assert(fmt[1] == 0); /* V formats must be singetons */
recsize = TARGET_TV_SIZE;
} else {
recsize = WORDSIZE * strlen(fmt);
}
uint *d = cast(uint *, flashAlloc(L, n * recsize)); uint *d = cast(uint *, flashAlloc(L, n * recsize));
uint *dest = d; uint *dest = d;
...@@ -284,8 +291,8 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) { ...@@ -284,8 +291,8 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
switch (*p++) { switch (*p++) {
case 'A': case 'A':
toFlashAddr(L, *d, *cast(void**, s)); toFlashAddr(L, *d, *cast(void**, s));
d++;
s += FLASH_WORDS(size_t); s += FLASH_WORDS(size_t);
d++;
break; break;
case 'I': case 'I':
*d++ = *s++; *d++ = *s++;
...@@ -293,21 +300,22 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) { ...@@ -293,21 +300,22 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
case 'S': case 'S':
newts = resolveTString(L, *cast(TString **, s)); newts = resolveTString(L, *cast(TString **, s));
toFlashAddr(L, *d, newts); toFlashAddr(L, *d, newts);
d++;
s += FLASH_WORDS(size_t); s += FLASH_WORDS(size_t);
d++;
break; break;
case 'V': case 'V':
memcpy(d, s, sizeof(TValue)); /* This code has to work for both Integer and Float build variants */
memset(d, 0, TARGET_TV_SIZE);
TValue *sv = cast(TValue *, s); TValue *sv = cast(TValue *, s);
if (ttisstring(sv)) { if (ttisstring(sv)) {
newts = resolveTString(L, rawtsvalue(sv)); toFlashAddr(L, *d, resolveTString(L, rawtsvalue(sv)));
toFlashAddr(L, *d, newts); } else { /* non-collectable types all of size lua_Number */
d[1] = 0;
} else {
lua_assert(!iscollectable(sv)); lua_assert(!iscollectable(sv));
*cast(lua_Number*,d) = *cast(lua_Number*,s);
} }
d += FLASH_WORDS(TValue); *cast(int *,cast(lua_Number*,d)+1) = ttype(sv);
s += FLASH_WORDS(TValue); s += FLASH_WORDS(TValue);
d += TARGET_TV_SIZE/WORDSIZE;
break; break;
default: default:
lua_assert (0); lua_assert (0);
...@@ -334,7 +342,7 @@ static void *functionToFlash(lua_State* L, const Proto* orig) { ...@@ -334,7 +342,7 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
memcpy (&f, orig, sizeof(Proto)); memcpy (&f, orig, sizeof(Proto));
f.gclist = NULL; f.gclist = NULL;
f.next = NULL; f.next = NULL;
l_setbit(f.marked, FIXEDBIT); l_setbit(f.marked, LFSBIT); /* OK to set the LFSBIT on a stack-cloned copy */
if (f.sizep) { /* clone included Protos */ if (f.sizep) { /* clone included Protos */
Proto **p = luaM_newvector(L, f.sizep, Proto *); Proto **p = luaM_newvector(L, f.sizep, Proto *);
......
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
*/ */
// #include "c_errno.h" #include <errno.h>
#include "c_stdio.h" #include <stdio.h>
#include "c_stdlib.h" #include <stdlib.h>
#include "c_string.h" #include <string.h>
#include "vfs.h"
#define liolib_c #define liolib_c
#define LUA_LIB #define LUA_LIB
#define LUA_OPTIMIZE_MEMORY 2
#include "lua.h" #include "lua.h"
...@@ -20,26 +20,21 @@ ...@@ -20,26 +20,21 @@
#include "lualib.h" #include "lualib.h"
#include "lrotable.h" #include "lrotable.h"
#define IO_INPUT 1 #define IO_INPUT 1
#define IO_OUTPUT 2 #define IO_OUTPUT 2
#define IO_STDERR 0 #define IO_STDERR 0
#if LUA_OPTIMIZE_MEMORY != 2 #define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_ENVIRONINDEX, f) #define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_ENVIRONINDEX, f)
#else
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX, liolib_keys[f])
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[f])
/* "Pseudo-random" keys for the registry */ /* "Pseudo-random" keys for the registry */
static const int liolib_keys[] = {(int)&luaL_callmeta, (int)&luaL_typerror, (int)&luaL_argerror}; static const size_t liolib_keys[] = {(size_t)&luaL_callmeta, (size_t)&luaL_typerror, (size_t)&luaL_argerror};
#endif
static const char *const fnames[] = {"input", "output"}; static const char *const fnames[] = {"input", "output"};
static int pushresult (lua_State *L, int i, const char *filename) { static int pushresult (lua_State *L, int i, const char *filename) {
int en = vfs_ferrno(0); /* calls to Lua API may change this value */ int en = errno; /* calls to Lua API may change this value */
if (i) { if (i) {
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
return 1; return 1;
...@@ -47,9 +42,9 @@ static int pushresult (lua_State *L, int i, const char *filename) { ...@@ -47,9 +42,9 @@ static int pushresult (lua_State *L, int i, const char *filename) {
else { else {
lua_pushnil(L); lua_pushnil(L);
if (filename) if (filename)
lua_pushfstring(L, "%s: err(%d)", filename, en); lua_pushfstring(L, "%s: %s", filename, strerror(en));
else else
lua_pushfstring(L, "err(%d)", en); lua_pushfstring(L, "%s", strerror(en));
lua_pushinteger(L, en); lua_pushinteger(L, en);
return 3; return 3;
} }
...@@ -57,12 +52,12 @@ static int pushresult (lua_State *L, int i, const char *filename) { ...@@ -57,12 +52,12 @@ static int pushresult (lua_State *L, int i, const char *filename) {
static void fileerror (lua_State *L, int arg, const char *filename) { static void fileerror (lua_State *L, int arg, const char *filename) {
lua_pushfstring(L, "%s: err(%d)", filename, vfs_ferrno(0)); lua_pushfstring(L, "%s: %s", filename, strerror(errno));
luaL_argerror(L, arg, lua_tostring(L, -1)); luaL_argerror(L, arg, lua_tostring(L, -1));
} }
#define tofilep(L) ((int *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) #define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
static int io_type (lua_State *L) { static int io_type (lua_State *L) {
...@@ -72,7 +67,7 @@ static int io_type (lua_State *L) { ...@@ -72,7 +67,7 @@ static int io_type (lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE); lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1)) if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
lua_pushnil(L); /* not a file */ lua_pushnil(L); /* not a file */
else if (*((int *)ud) < FS_OPEN_OK) else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, "closed file"); lua_pushliteral(L, "closed file");
else else
lua_pushliteral(L, "file"); lua_pushliteral(L, "file");
...@@ -80,9 +75,9 @@ static int io_type (lua_State *L) { ...@@ -80,9 +75,9 @@ static int io_type (lua_State *L) {
} }
static int tofile (lua_State *L) { static FILE *tofile (lua_State *L) {
int *f = tofilep(L); FILE **f = tofilep(L);
if (*f < FS_OPEN_OK) if (*f == NULL)
luaL_error(L, "attempt to use a closed file"); luaL_error(L, "attempt to use a closed file");
return *f; return *f;
} }
...@@ -94,91 +89,52 @@ static int tofile (lua_State *L) { ...@@ -94,91 +89,52 @@ static int tofile (lua_State *L) {
** before opening the actual file; so, if there is a memory error, the ** before opening the actual file; so, if there is a memory error, the
** file is not left opened. ** file is not left opened.
*/ */
static int *newfile (lua_State *L) { static FILE **newfile (lua_State *L) {
int *pf = (int *)lua_newuserdata(L, sizeof(int)); FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
*pf = FS_OPEN_OK - 1; /* file handle is currently `closed' */ *pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE); luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
return pf; return pf;
} }
#if LUA_OPTIMIZE_MEMORY != 2
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
static int io_noclose (lua_State *L) {
lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
#if 0
/*
** function to close 'popen' files
*/
static int io_pclose (lua_State *L) {
int *p = tofilep(L);
int ok = lua_pclose(L, *p);
*p = FS_OPEN_OK - 1;
return pushresult(L, ok, NULL);
}
#endif
/*
** function to close regular files
*/
static int io_fclose (lua_State *L) {
int *p = tofilep(L);
int ok = (vfs_close(*p) == 0);
*p = FS_OPEN_OK - 1;
return pushresult(L, ok, NULL);
}
#endif
static int aux_close (lua_State *L) { static int aux_close (lua_State *L) {
#if LUA_OPTIMIZE_MEMORY != 2 FILE **p = tofilep(L);
lua_getfenv(L, 1); if(*p == stdin || *p == stdout || *p == stderr)
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
#else
int *p = tofilep(L);
if(*p == c_stdin || *p == c_stdout || *p == c_stderr)
{ {
lua_pushnil(L); lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file"); lua_pushliteral(L, "cannot close standard file");
return 2; return 2;
} }
int ok = (vfs_close(*p) == 0); int ok = (fclose(*p) == 0);
*p = FS_OPEN_OK - 1; *p = NULL;
return pushresult(L, ok, NULL); return pushresult(L, ok, NULL);
#endif
} }
static int io_close (lua_State *L) { static int io_close (lua_State *L) {
if (lua_isnone(L, 1)) if (lua_isnone(L, 1))
LUA_IO_GETFIELD(IO_OUTPUT); lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
tofile(L); /* make sure argument is a file */ tofile(L); /* make sure argument is a file */
return aux_close(L); return aux_close(L);
} }
static int io_gc (lua_State *L) { static int io_gc (lua_State *L) {
int f = *tofilep(L); FILE *f = *tofilep(L);
/* ignore closed files */ /* ignore closed files */
if (f != FS_OPEN_OK - 1) if (f != NULL)
aux_close(L); aux_close(L);
return 0; return 0;
} }
static int io_tostring (lua_State *L) { static int io_tostring (lua_State *L) {
int f = *tofilep(L); FILE *f = *tofilep(L);
if (f == FS_OPEN_OK - 1) if (f == NULL)
lua_pushliteral(L, "file (closed)"); lua_pushliteral(L, "file (closed)");
else else
lua_pushfstring(L, "file (%i)", f); lua_pushfstring(L, "file (%p)", f);
return 1; return 1;
} }
...@@ -186,42 +142,19 @@ static int io_tostring (lua_State *L) { ...@@ -186,42 +142,19 @@ static int io_tostring (lua_State *L) {
static int io_open (lua_State *L) { static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r"); const char *mode = luaL_optstring(L, 2, "r");
int *pf = newfile(L); FILE **pf = newfile(L);
*pf = vfs_open(filename, mode); *pf = fopen(filename, mode);
return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, filename) : 1; return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
/*
** this function has a separated environment, which defines the
** correct __close for 'popen' files
*/
#if 0
static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
int *pf = newfile(L);
*pf = lua_popen(L, filename, fs_mode2flags(mode));
return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, filename) : 1;
} }
static int io_tmpfile (lua_State *L) { static FILE *getiofile (lua_State *L, int findex) {
int *pf = newfile(L); FILE *f;
*pf = tmpfile(); lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, NULL) : 1; f = *(FILE **)lua_touserdata(L, -1);
} if (f == NULL)
#endif luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
return f;
static int getiofile (lua_State *L, int findex) {
int *pf;
LUA_IO_GETFIELD(findex);
pf = (int *)lua_touserdata(L, -1);
if (pf == NULL || *pf == FS_OPEN_OK - 1){
luaL_error(L, "default %s file is closed", fnames[findex - 1]);
return FS_OPEN_OK - 1;
}
return *pf;
} }
...@@ -229,19 +162,19 @@ static int g_iofile (lua_State *L, int f, const char *mode) { ...@@ -229,19 +162,19 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
if (!lua_isnoneornil(L, 1)) { if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1); const char *filename = lua_tostring(L, 1);
if (filename) { if (filename) {
int *pf = newfile(L); FILE **pf = newfile(L);
*pf = vfs_open(filename, mode); *pf = fopen(filename, mode);
if (*pf == FS_OPEN_OK - 1) if (*pf == NULL)
fileerror(L, 1, filename); fileerror(L, 1, filename);
} }
else { else {
tofile(L); /* check that it's a valid file handle */ tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1); lua_pushvalue(L, 1);
} }
LUA_IO_SETFIELD(f); lua_rawseti(L, LUA_ENVIRONINDEX, f);
} }
/* return current value */ /* return current value */
LUA_IO_GETFIELD(f); lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1; return 1;
} }
...@@ -276,14 +209,14 @@ static int f_lines (lua_State *L) { ...@@ -276,14 +209,14 @@ static int f_lines (lua_State *L) {
static int io_lines (lua_State *L) { static int io_lines (lua_State *L) {
if (lua_isnoneornil(L, 1)) { /* no arguments? */ if (lua_isnoneornil(L, 1)) { /* no arguments? */
/* will iterate over default input */ /* will iterate over default input */
LUA_IO_GETFIELD(IO_INPUT); lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L); return f_lines(L);
} }
else { else {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
int *pf = newfile(L); FILE **pf = newfile(L);
*pf = vfs_open(filename, "r"); *pf = fopen(filename, "r");
if (*pf == FS_OPEN_OK - 1) if (*pf == NULL)
fileerror(L, 1, filename); fileerror(L, 1, filename);
aux_lines(L, lua_gettop(L), 1); aux_lines(L, lua_gettop(L), 1);
return 1; return 1;
...@@ -297,10 +230,10 @@ static int io_lines (lua_State *L) { ...@@ -297,10 +230,10 @@ static int io_lines (lua_State *L) {
** ======================================================= ** =======================================================
*/ */
#if 0
static int read_number (lua_State *L, int f) { static int read_number (lua_State *L, FILE *f) {
lua_Number d; lua_Number d;
if (fs_scanf(f, LUA_NUMBER_SCAN, &d) == 1) { if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
lua_pushnumber(L, d); lua_pushnumber(L, d);
return 1; return 1;
} }
...@@ -309,27 +242,27 @@ static int read_number (lua_State *L, int f) { ...@@ -309,27 +242,27 @@ static int read_number (lua_State *L, int f) {
return 0; /* read fails */ return 0; /* read fails */
} }
} }
#endif
static int test_eof (lua_State *L, int f) {
int c = vfs_getc(f); static int test_eof (lua_State *L, FILE *f) {
vfs_ungetc(c, f); int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0); lua_pushlstring(L, NULL, 0);
return (c != EOF); return (c != EOF);
} }
#if 0
static int read_line (lua_State *L, int f) { static int read_line (lua_State *L, FILE *f) {
luaL_Buffer b; luaL_Buffer b;
luaL_buffinit(L, &b); luaL_buffinit(L, &b);
for (;;) { for (;;) {
size_t l; size_t l;
char *p = luaL_prepbuffer(&b); char *p = luaL_prepbuffer(&b);
if (fs_gets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
luaL_pushresult(&b); /* close buffer */ luaL_pushresult(&b); /* close buffer */
return (lua_objlen(L, -1) > 0); /* check whether read something */ return (lua_objlen(L, -1) > 0); /* check whether read something */
} }
l = c_strlen(p); l = strlen(p);
if (l == 0 || p[l-1] != '\n') if (l == 0 || p[l-1] != '\n')
luaL_addsize(&b, l); luaL_addsize(&b, l);
else { else {
...@@ -339,27 +272,9 @@ static int read_line (lua_State *L, int f) { ...@@ -339,27 +272,9 @@ static int read_line (lua_State *L, int f) {
} }
} }
} }
#else
static int read_line (lua_State *L, int f) {
luaL_Buffer b;
luaL_buffinit(L, &b);
signed char c;
do {
c = (signed char)vfs_getc(f);
if (c==EOF) {
break;
}
if (c != '\n') {
luaL_addchar(&b, c);
}
} while (c != '\n');
luaL_pushresult(&b); /* close buffer */
return (lua_objlen(L, -1) > 0); /* check whether read something */
}
#endif
static int read_chars (lua_State *L, int f, size_t n) { static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t rlen; /* how much to read */ size_t rlen; /* how much to read */
size_t nr; /* number of chars actually read */ size_t nr; /* number of chars actually read */
luaL_Buffer b; luaL_Buffer b;
...@@ -368,7 +283,7 @@ static int read_chars (lua_State *L, int f, size_t n) { ...@@ -368,7 +283,7 @@ static int read_chars (lua_State *L, int f, size_t n) {
do { do {
char *p = luaL_prepbuffer(&b); char *p = luaL_prepbuffer(&b);
if (rlen > n) rlen = n; /* cannot read more than asked */ if (rlen > n) rlen = n; /* cannot read more than asked */
nr = vfs_read(f, p, rlen); nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr); luaL_addsize(&b, nr);
n -= nr; /* still have to read `n' chars */ n -= nr; /* still have to read `n' chars */
} while (n > 0 && nr == rlen); /* until end of count or eof */ } while (n > 0 && nr == rlen); /* until end of count or eof */
...@@ -377,11 +292,11 @@ static int read_chars (lua_State *L, int f, size_t n) { ...@@ -377,11 +292,11 @@ static int read_chars (lua_State *L, int f, size_t n) {
} }
static int g_read (lua_State *L, int f, int first) { static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1; int nargs = lua_gettop(L) - 1;
int success; int success;
int n; int n;
//vfs_clearerr(f); clearerr(f);
if (nargs == 0) { /* no arguments? */ if (nargs == 0) { /* no arguments? */
success = read_line(L, f); success = read_line(L, f);
n = first+1; /* to return 1 result */ n = first+1; /* to return 1 result */
...@@ -398,11 +313,9 @@ static int g_read (lua_State *L, int f, int first) { ...@@ -398,11 +313,9 @@ static int g_read (lua_State *L, int f, int first) {
const char *p = lua_tostring(L, n); const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) { switch (p[1]) {
#if 0
case 'n': /* number */ case 'n': /* number */
success = read_number(L, f); success = read_number(L, f);
break; break;
#endif
case 'l': /* line */ case 'l': /* line */
success = read_line(L, f); success = read_line(L, f);
break; break;
...@@ -416,7 +329,7 @@ static int g_read (lua_State *L, int f, int first) { ...@@ -416,7 +329,7 @@ static int g_read (lua_State *L, int f, int first) {
} }
} }
} }
if (vfs_ferrno(f)) if (ferror(f))
return pushresult(L, 0, NULL); return pushresult(L, 0, NULL);
if (!success) { if (!success) {
lua_pop(L, 1); /* remove last result */ lua_pop(L, 1); /* remove last result */
...@@ -437,15 +350,13 @@ static int f_read (lua_State *L) { ...@@ -437,15 +350,13 @@ static int f_read (lua_State *L) {
static int io_readline (lua_State *L) { static int io_readline (lua_State *L) {
int *pf = (int *)lua_touserdata(L, lua_upvalueindex(1)); FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess; int sucess;
if (pf == NULL || *pf == FS_OPEN_OK - 1){ /* file is already closed? */ if (f == NULL) /* file is already closed? */
luaL_error(L, "file is already closed"); luaL_error(L, "file is already closed");
return 0; sucess = read_line(L, f);
} if (ferror(f))
sucess = read_line(L, *pf); return luaL_error(L, "%s", strerror(errno));
if (vfs_ferrno(*pf))
return luaL_error(L, "err(%d)", vfs_ferrno(*pf));
if (sucess) return 1; if (sucess) return 1;
else { /* EOF */ else { /* EOF */
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
...@@ -460,22 +371,19 @@ static int io_readline (lua_State *L) { ...@@ -460,22 +371,19 @@ static int io_readline (lua_State *L) {
/* }====================================================== */ /* }====================================================== */
static int g_write (lua_State *L, int f, int arg) { static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - 1; int nargs = lua_gettop(L) - 1;
int status = 1; int status = 1;
for (; nargs--; arg++) { for (; nargs--; arg++) {
#if 0
if (lua_type(L, arg) == LUA_TNUMBER) { if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */ /* optimization: could be done exactly as for strings */
status = status && status = status &&
fs_printf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
} }
else else {
#endif
{
size_t l; size_t l;
const char *s = luaL_checklstring(L, arg, &l); const char *s = luaL_checklstring(L, arg, &l);
status = status && (vfs_write(f, s, l) == l); status = status && (fwrite(s, sizeof(char), l, f) == l);
} }
} }
return pushresult(L, status, NULL); return pushresult(L, status, NULL);
...@@ -493,75 +401,68 @@ static int f_write (lua_State *L) { ...@@ -493,75 +401,68 @@ static int f_write (lua_State *L) {
static int f_seek (lua_State *L) { static int f_seek (lua_State *L) {
static const int mode[] = {VFS_SEEK_SET, VFS_SEEK_CUR, VFS_SEEK_END}; static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL}; static const char *const modenames[] = {"set", "cur", "end", NULL};
int f = tofile(L); FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames); int op = luaL_checkoption(L, 2, "cur", modenames);
long offset = luaL_optlong(L, 3, 0); long offset = luaL_optlong(L, 3, 0);
op = vfs_lseek(f, offset, mode[op]); op = fseek(f, offset, mode[op]);
if (op) if (op)
return pushresult(L, 0, NULL); /* error */ return pushresult(L, 0, NULL); /* error */
else { else {
lua_pushinteger(L, vfs_tell(f)); lua_pushinteger(L, ftell(f));
return 1; return 1;
} }
} }
#if 0
static int f_setvbuf (lua_State *L) { static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL}; static const char *const modenames[] = {"no", "full", "line", NULL};
int f = tofile(L); FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames); int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], sz); int res = setvbuf(f, NULL, mode[op], sz);
return pushresult(L, res == 0, NULL); return pushresult(L, res == 0, NULL);
} }
#endif
static int io_flush (lua_State *L) { static int io_flush (lua_State *L) {
return pushresult(L, vfs_flush(getiofile(L, IO_OUTPUT)) == 0, NULL); return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
} }
static int f_flush (lua_State *L) { static int f_flush (lua_State *L) {
return pushresult(L, vfs_flush(tofile(L)) == 0, NULL); return pushresult(L, fflush(tofile(L)) == 0, NULL);
} }
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 2 #define MIN_OPT_LEVEL 2
#include "lrodefs.h" #include "lrodefs.h"
#if LUA_OPTIMIZE_MEMORY == 2
const LUA_REG_TYPE iolib_funcs[] = { const LUA_REG_TYPE iolib_funcs[] = {
#else
const LUA_REG_TYPE iolib[] = {
#endif
{LSTRKEY("close"), LFUNCVAL(io_close)}, {LSTRKEY("close"), LFUNCVAL(io_close)},
{LSTRKEY("flush"), LFUNCVAL(io_flush)}, {LSTRKEY("flush"), LFUNCVAL(io_flush)},
{LSTRKEY("input"), LFUNCVAL(io_input)}, {LSTRKEY("input"), LFUNCVAL(io_input)},
{LSTRKEY("lines"), LFUNCVAL(io_lines)}, {LSTRKEY("lines"), LFUNCVAL(io_lines)},
{LSTRKEY("open"), LFUNCVAL(io_open)}, {LSTRKEY("open"), LFUNCVAL(io_open)},
{LSTRKEY("output"), LFUNCVAL(io_output)}, {LSTRKEY("output"), LFUNCVAL(io_output)},
// {LSTRKEY("popen"), LFUNCVAL(io_popen)},
{LSTRKEY("read"), LFUNCVAL(io_read)}, {LSTRKEY("read"), LFUNCVAL(io_read)},
// {LSTRKEY("tmpfile"), LFUNCVAL(io_tmpfile)},
{LSTRKEY("type"), LFUNCVAL(io_type)}, {LSTRKEY("type"), LFUNCVAL(io_type)},
{LSTRKEY("write"), LFUNCVAL(io_write)}, {LSTRKEY("write"), LFUNCVAL(io_write)},
{LSTRKEY("__index"), LROVAL(iolib_funcs)},
{LNILKEY, LNILVAL} {LNILKEY, LNILVAL}
}; };
#if LUA_OPTIMIZE_MEMORY == 2 /* Note that IO objects use a RAM metatable created to allow extensibility */
static int luaL_index(lua_State *L)
static int io_index(lua_State *L)
{ {
return luaR_findfunction(L, iolib_funcs); return luaR_findfunction(L, iolib_funcs);
} }
const luaL_Reg iolib[] = { const luaL_Reg iolib[] = {
{"__index", luaL_index}, {"__index", io_index},
{NULL, NULL} {NULL, NULL}
}; };
#endif
#undef MIN_OPT_LEVEL #undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1 #define MIN_OPT_LEVEL 1
...@@ -572,80 +473,31 @@ const LUA_REG_TYPE flib[] = { ...@@ -572,80 +473,31 @@ const LUA_REG_TYPE flib[] = {
{LSTRKEY("lines"), LFUNCVAL(f_lines)}, {LSTRKEY("lines"), LFUNCVAL(f_lines)},
{LSTRKEY("read"), LFUNCVAL(f_read)}, {LSTRKEY("read"), LFUNCVAL(f_read)},
{LSTRKEY("seek"), LFUNCVAL(f_seek)}, {LSTRKEY("seek"), LFUNCVAL(f_seek)},
// {LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)}, {LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)},
{LSTRKEY("write"), LFUNCVAL(f_write)}, {LSTRKEY("write"), LFUNCVAL(f_write)},
{LSTRKEY("__gc"), LFUNCVAL(io_gc)}, {LSTRKEY("__gc"), LFUNCVAL(io_gc)},
{LSTRKEY("__tostring"), LFUNCVAL(io_tostring)}, {LSTRKEY("__tostring"), LFUNCVAL(io_tostring)},
#if LUA_OPTIMIZE_MEMORY > 0
{LSTRKEY("__index"), LROVAL(flib)}, {LSTRKEY("__index"), LROVAL(flib)},
#endif
{LNILKEY, LNILVAL} {LNILKEY, LNILVAL}
}; };
static void createmeta (lua_State *L) {
#if LUA_OPTIMIZE_MEMORY == 0
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_register(L, NULL, flib); /* file methods */
#else
luaL_rometatable(L, LUA_FILEHANDLE, (void*)flib); /* create metatable for file handles */
#endif
}
static void createstdfile (lua_State *L, int f, int k, const char *fname) { static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f; *newfile(L) = f;
#if LUA_OPTIMIZE_MEMORY != 2
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
lua_pushvalue(L, -2); /* copy environment */
lua_setfenv(L, -2); /* set it */
lua_setfield(L, -3, fname);
#else
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_rawseti(L, LUA_REGISTRYINDEX, liolib_keys[k]); lua_rawseti(L, LUA_REGISTRYINDEX, (int)(liolib_keys[k]));
lua_setfield(L, -2, fname); lua_setfield(L, -2, fname);
#endif
} }
#if LUA_OPTIMIZE_MEMORY != 2
static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
lua_pushcfunction(L, cls);
lua_setfield(L, -2, "__close");
}
#endif
LUALIB_API int luaopen_io (lua_State *L) { LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L); luaL_rometatable(L, LUA_FILEHANDLE, (void*)flib); /* create metatable for file handles */
#if LUA_OPTIMIZE_MEMORY != 2
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
newfenv(L, io_fclose);
lua_replace(L, LUA_ENVIRONINDEX);
/* open library */
luaL_register(L, LUA_IOLIBNAME, iolib);
newfenv(L, io_noclose); /* close function for default files */
#else
luaL_register_light(L, LUA_IOLIBNAME, iolib); luaL_register_light(L, LUA_IOLIBNAME, iolib);
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
#endif
#if 0
/* create (and set) default files */ /* create (and set) default files */
createstdfile(L, c_stdin, IO_INPUT, "stdin"); createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, c_stdout, IO_OUTPUT, "stdout"); createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, c_stderr, IO_STDERR, "stderr"); createstdfile(L, stderr, 0, "stderr");
#if LUA_OPTIMIZE_MEMORY != 2
lua_pop(L, 1); /* pop environment for default files */
lua_getfield(L, -1, "popen");
newfenv(L, io_pclose); /* create environment for 'popen' */
lua_setfenv(L, -2); /* set fenv for 'popen' */
lua_pop(L, 1); /* pop 'popen' */
#endif
#endif
return 1; return 1;
} }
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