Unverified Commit 27a83feb authored by Terry Ellison's avatar Terry Ellison Committed by GitHub
Browse files

Merge pull request #2301 from TerryE/dev-LFS

LFS evaluation version -- second release
parents 2cc195d5 a3c2f48f
...@@ -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);
...@@ -127,10 +127,15 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) { ...@@ -127,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
...@@ -445,6 +445,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { ...@@ -445,6 +445,7 @@ 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);
if (t->node != dummynode || nhsize>0)
resize_hashpart(L, t, nhsize); 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;
...@@ -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
...@@ -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);
......
...@@ -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
...@@ -56,9 +57,10 @@ ...@@ -56,9 +57,10 @@
#define c_strrchr strrchr #define c_strrchr strrchr
#define c_strstr strstr #define c_strstr strstr
double c_strtod(const char *__n, char **__end_PTR); double c_strtod(const char *__n, char **__end_PTR);
#define c_strtoul strtoul
#define c_ungetc ungetc #define c_ungetc ungetc
#define c_strtol strtol
#define c_strtoul strtoul
#define dbg_printf printf
#else #else
#define C_HEADER_ASSERT "c_assert.h" #define C_HEADER_ASSERT "c_assert.h"
......
#
# This Make file is called from the core Makefile hierarchy with is a hierarchical
# make wwhich uses parent callbacks to implement inheritance. However is luac_cross
# build stands outside this and uses the host toolchain to implement a separate
# host build of the luac.cross image.
#
.NOTPARALLEL:
CCFLAGS:= -I.. -I../../include -I../../../include -I ../../libc
LDFLAGS:= -L$(SDK_DIR)/lib -L$(SDK_DIR)/ld -lm -ldl -Wl,-Map=mapfile
CCFLAGS += -Wall
DEFINES += -DLUA_CROSS_COMPILER -DLUA_OPTIMIZE_MEMORY=2
TARGET = host
ifeq ($(FLAVOR),debug)
CCFLAGS += -O0 -g
TARGET_LDFLAGS += -O0 -g
else
FLAVOR = release
CCFLAGS += -O2
TARGET_LDFLAGS += -O2
endif
LUACSRC := luac.c lflashimg.c liolib.c loslib.c print.c
LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c \
ldo.c ldump.c lfunc.c lgc.c linit.c llex.c \
lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c lparser.c \
lrotable.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
ltm.c lundump.c lvm.c lzio.c
LIBCSRC := c_stdlib.c
#
# This relies on the files being unique on the vpath
#
SRC := $(LUACSRC) $(LUASRC) $(LIBCSRC)
vpath %.c .:..:../../libc
ODIR := .output/$(TARGET)/$(FLAVOR)/obj
OBJS := $(SRC:%.c=$(ODIR)/%.o)
DEPS := $(SRC:%.c=$(ODIR)/%.d)
CFLAGS = $(CCFLAGS) $(DEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
DFLAGS = $(CCFLAGS) $(DDEFINES) $(EXTRA_CCFLAGS) $(STD_CFLAGS) $(INCLUDES)
CC := gcc
ECHO := echo
IMAGE := ../../../luac.cross
.PHONY: test clean all
all: $(DEPS) $(IMAGE)
$(IMAGE) : $(OBJS)
$(CC) $(OBJS) -o $@ $(LDFLAGS)
test :
@echo CC: $(CC)
@echo SRC: $(SRC)
@echo OBJS: $(OBJS)
@echo DEPS: $(DEPS)
clean :
$(RM) -r $(ODIR)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
endif
$(ODIR)/%.o: %.c
@mkdir -p $(ODIR);
$(CC) $(if $(findstring $<,$(DSRCS)),$(DFLAGS),$(CFLAGS)) $(COPTS_$(*F)) -o $@ -c $<
$(ODIR)/%.d: %.c
@mkdir -p $(ODIR);
@echo DEPEND: $(CC) -M $(CFLAGS) $<
@set -e; rm -f $@; \
$(CC) -M $(CFLAGS) $< > $@.$$$$; \
sed 's,\($*\.o\)[ :]*,$(ODIR)/\1 $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
/*
** lflashimg.c
** Dump a compiled Proto hiearchy to a RO (FLash) image file
** See Copyright Notice in lua.h
*/
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include C_HEADER_CTYPE
#include C_HEADER_STDIO
#include C_HEADER_STDLIB
#include C_HEADER_STRING
#define lflashimg_c
#define LUA_CORE
#include "lobject.h"
#include "lstring.h"
#undef LUA_FLASH_STORE
#define LUA_FLASH_STORE
#include "lflash.h"
//#define LOCAL_DEBUG
#if INT_MAX != 2147483647
# error "luac.cross requires C toolchain with 4 byte word size"
#endif
#define WORDSIZE ((int) sizeof(int))
#define ALIGN(s) (((s)+(WORDSIZE-1)) & (-(signed) WORDSIZE))
#define WORDSHIFT 2
typedef unsigned int uint;
#define FLASH_WORDS(t) (sizeof(t)/sizeof(FlashAddr))
/*
*
* This dumper is a variant of the standard ldump, in that instead of producing a
* binary loader format that lundump can load, it produces an image file that can be
* directly mapped or copied into addressable memory. The typical application is on
* small memory IoT devices which support programmable flash storage such as the
* ESP8266. A 64 Kb LFS image has 16Kb words and will enable all program-related
* storage to be accessed directly from flash, leaving the RAM for true R/W
* application data.
*
* The start address of the Lua Flash Store (LFS) is build-dependent, and the cross
* compiler '-a' option allows the developer to fix the LFS at a defined flash memory
* address. Alternatively and by default the cross compilation adopts a position
* independent image format, which permits the on-device image loader to load the LFS
* image at an appropriate base within the flash address space. As all objects in the
* LFS can be treated as multiples of 4-byte words, also all address fields are both
* word aligned, and any address references within the LFS are also word-aligned,
* such addresses are stored in a special format, where each PI address is two
* 16-bit unsigned offsets:
*
* Bits 0-15 is the offset into the LFS that this address refers to
* Bits 16-31 is the offset linking to the PIC next address.
*
* Hence the LFS can be up to 256Kb in length and the flash loader can use the forward
* links to chain down PI address from the mainProto address at offet 3 to all image
* addresses during load and convert them to the corresponding correct absolute memory
* addresses. This reloation process is skipped for absolute addressed images (which
* are identified by the FLASH_SIG_ABSOLUTE bit setting in the flash signature.
*
* The flash image has a standard header detailed in lflash.h
*
* Note that luac.cross may be compiled on any little-endian machine with 32 or 64 bit
* word length so Flash addresses can't be handled as standard C pointers as size_t
* and int may not have the same size. Hence addresses with the must be declared as
* the FlashAddr type rather than typed C pointers and must be accessed through macros.
*
* ALso note that image built with a given LUA_PACK_TVALUES / LUA_NUNBER_INTEGRAL
* combination must be loaded into a corresponding firmware build. Hence these
* configuration options are also included in the FLash Signature.
*
* The Flash image is assembled up by first building the RO stringtable containing
* all strings used in the compiled proto hierarchy. This is followed by the Protos.
*
* The storage is allocated bottom up using a serial allocator and the algortihm for
* building the image essentially does a bottom-uo serial enumeration so that any
* referenced storage has already been allocated in the image, and therefore (with the
* exception of the Flash Header) all pointer references are backwards.
*
* As addresses are 4 byte on the target and either 4 or (typically) 8 bytes on the
* host so any structures containing address fields (TStrings, TValues, Protos, other
* address vectors) need repacking.
*/
typedef struct flashts { /* This is the fixed 32-bit equivalent of TString */
FlashAddr next;
lu_byte tt;
lu_byte marked;
int hash;
int len;
} FlashTS;
#ifndef LUA_MAX_FLASH_SIZE
#define LUA_MAX_FLASH_SIZE 0x10000 //in words
#endif
static uint curOffset = 0;
static uint flashImage[LUA_MAX_FLASH_SIZE];
static unsigned char flashAddrTag[LUA_MAX_FLASH_SIZE/WORDSIZE];
#define fatal luac_fatal
extern void __attribute__((noreturn)) luac_fatal(const char* message);
#ifdef LOCAL_DEBUG
#define DBG_PRINT(...) printf(__VA_ARGS__)
#else
#define DBG_PRINT(...) ((void)0)
#endif
/*
* Serial allocator. Throw a luac-style out of memory error is allocaiton fails.
*/
static void *flashAlloc(lua_State* L, size_t n) {
void *p = (void *)(flashImage + curOffset);
curOffset += ALIGN(n)>>WORDSHIFT;
if (curOffset > LUA_MAX_FLASH_SIZE) {
fatal("Out of Flash memmory");
}
return p;
}
/*
* Convert an absolute address pointing inside the flash image to offset form.
* This macro form also takes the lvalue destination so that this can be tagged
* as a relocatable address.
*/
#define toFlashAddr(l, pd, s) _toFlashAddr(l, &(pd), s)
static void _toFlashAddr(lua_State* L, FlashAddr *a, void *p) {
uint doffset = cast(char *, a) - cast(char *,flashImage);
lua_assert(!(doffset & (WORDSIZE-1)));
doffset >>= WORDSHIFT;
lua_assert(doffset <= curOffset);
if (p) {
uint poffset = cast(char *, p) - cast(char *,flashImage);
lua_assert(!(poffset & (WORDSIZE-1)));
poffset >>= WORDSHIFT;
lua_assert(poffset <= curOffset);
flashImage[doffset] = poffset; // Set the pointer to the offset
flashAddrTag[doffset] = 1; // And tag as an address
} else { // Special case for NULL pointer
flashImage[doffset] = 0;
}
}
/*
* Convert an image address in offset form back to (host) absolute form
*/
static void *fromFashAddr(FlashAddr a) {
return a ? cast(void *, flashImage + a) : NULL;
}
/*
* Add a TS found in the Proto Load to the table at the ToS
*/
static void addTS(lua_State *L, TString *ts) {
lua_assert(ts->tsv.tt==LUA_TSTRING);
lua_pushnil(L);
setsvalue(L, L->top-1, ts);
lua_pushinteger(L, 1);
lua_rawset(L, -3);
DBG_PRINT("Adding string: %s\n",getstr(ts));
}
/*
* Enumerate all of the Protos in the Proto hiearchy and scan contents to collect
* all referenced strings in a Lua Array at ToS.
*/
static void scanProtoStrings(lua_State *L, const Proto* f) {
/* Table at L->Top[-1] is used to collect the strings */
int i;
if (f->source)
addTS(L, f->source);
#ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo)
addTS(L, luaS_new(L, cast(const char *, f->packedlineinfo)));
#endif
for (i = 0; i < f->sizek; i++) {
if (ttisstring(f->k + i))
addTS(L, rawtsvalue(f->k + i));
}
for (i = 0; i < f->sizeupvalues; i++) addTS(L, f->upvalues[i]);
for (i = 0; i < f->sizelocvars; i++) addTS(L, f->locvars[i].varname);
for (i = 0; i < f->sizep; i++) scanProtoStrings(L, f->p[i]);
}
/*
* Use the collected strings table to build the new ROstrt in the Flash Image
*
* The input is an array of {"SomeString" = 1, ...} on the ToS.
* The output is an array of {"SomeString" = FlashOffset("SomeString"), ...} on ToS
*/
static void createROstrt(lua_State *L, FlashHeader *fh) {
/* Table at L->Top[-1] on input is hash used to collect the strings */
/* Count the number of strings. Can't use objlen as this is a hash */
fh->nROuse = 0;
lua_pushnil(L); /* first key */
while (lua_next(L, -2) != 0) {
fh->nROuse++;
DBG_PRINT("Found: %s\n",getstr(rawtsvalue(L->top-2)));
lua_pop(L, 1); // dump the value
}
fh->nROsize = 2<<luaO_log2(fh->nROuse);
FlashAddr *hashTab = flashAlloc(L, fh->nROsize * WORDSIZE);
toFlashAddr(L, fh->pROhash, hashTab);
/* Now iterate over the strings to be added to the RO string table and build it */
lua_newtable(L); // add output table
lua_pushnil(L); // First key
while (lua_next(L, -3) != 0) { // replaces key, pushes value
TString *ts = rawtsvalue(L->top - 2); // key.ts
const char *p = getstr(ts); // C string of key
uint hash = ts->tsv.hash; // hash of key
size_t len = ts->tsv.len; // and length
DBG_PRINT("2nd pass: %s\n",p);
FlashAddr *e = hashTab + lmod(hash, fh->nROsize);
FlashTS *last = cast(FlashTS *, fromFashAddr(*e));
FlashTS *fts = cast(FlashTS *, flashAlloc(L, sizeof(FlashTS)));
toFlashAddr(L, *e, fts); // add reference to TS to lookup vector
toFlashAddr(L, fts->next, last); // and chain to previous entry if any
fts->tt = LUA_TSTRING; // Set as String
fts->marked = bitmask(LFSBIT); // LFS string with no Whitebits set
fts->hash = hash; // add hash
fts->len = len; // and length
memcpy(flashAlloc(L, ALIGN(len+1)), p, ALIGN(len+1)); // copy string
// include the trailing null char
lua_pop(L, 1); // Junk the value
lua_pushvalue(L, -1); // Dup the key as rawset dumps its copy
lua_pushinteger(L, cast(FlashAddr*,fts)-flashImage); // Value is new TS offset.
lua_rawset(L, -4); // Add to new table
}
/* At this point the old hash is done to derefence for GC */
lua_remove(L, -2);
}
/*
* Convert a TString reference in the host G(L)->strt entry into the corresponding
* TString address in the flashImage using the lookup table at ToS
*/
static void *resolveTString(lua_State* L, TString *s) {
if (!s)
return NULL;
lua_pushnil(L);
setsvalue(L, L->top-1, s);
lua_rawget(L, -2);
lua_assert(!lua_isnil(L, -1));
void *ts = fromFashAddr(lua_tointeger(L, -1));
lua_pop(L, 1);
return ts;
}
/*
* In order to simplify repacking of structures from the host format to that target
* format, this simple copy routine is data-driven by a simple format specifier.
* n Number of consecutive records to be processed
* fmt A string of A, I, S, V specifiers spanning the record.
* src Source of record
* returns Address of destination record
*/
#if defined(LUA_PACK_TVALUES)
#define TARGET_TV_SIZE (sizeof(lua_Number)+sizeof(lu_int32))
#else
#define TARGET_TV_SIZE (2*sizeof(lua_Number))
#endif
static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
/* ToS is the string address mapping table */
if (n == 0)
return NULL;
int i, recsize;
void *newts;
/* A bit of a botch because fmt is either "V" or a string of WORDSIZE specifiers */
/* The size 8 / 12 / 16 bytes for integer builds, packed TV and default TVs resp */
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 *dest = d;
uint *s = cast(uint *, src);
for (i = 0; i < n; i++) {
const char *p = fmt;
while (*p) {
/* All input address types (A,S,V) are aligned to size_t boundaries */
if (*p != 'I' && ((size_t)s)&(sizeof(size_t)-1))
s++;
switch (*p++) {
case 'A':
toFlashAddr(L, *d, *cast(void**, s));
s += FLASH_WORDS(size_t);
d++;
break;
case 'I':
*d++ = *s++;
break;
case 'S':
newts = resolveTString(L, *cast(TString **, s));
toFlashAddr(L, *d, newts);
s += FLASH_WORDS(size_t);
d++;
break;
case 'V':
/* This code has to work for both Integer and Float build variants */
memset(d, 0, TARGET_TV_SIZE);
TValue *sv = cast(TValue *, s);
if (ttisstring(sv)) {
toFlashAddr(L, *d, resolveTString(L, rawtsvalue(sv)));
} else { /* non-collectable types all of size lua_Number */
lua_assert(!iscollectable(sv));
*cast(lua_Number*,d) = *cast(lua_Number*,s);
}
*cast(int *,cast(lua_Number*,d)+1) = ttype(sv);
s += FLASH_WORDS(TValue);
d += TARGET_TV_SIZE/WORDSIZE;
break;
default:
lua_assert (0);
}
}
}
return dest;
}
/* The debug optimised version has a different Proto layout */
#ifdef LUA_OPTIMIZE_DEBUG
#define PROTO_COPY_MASK "AIAAAAAASIIIIIIIAI"
#else
#define PROTO_COPY_MASK "AIAAAAAASIIIIIIIIAI"
#endif
/*
* Do the actual prototype copy.
*/
static void *functionToFlash(lua_State* L, const Proto* orig) {
Proto f;
int i;
memcpy (&f, orig, sizeof(Proto));
f.gclist = NULL;
f.next = NULL;
l_setbit(f.marked, LFSBIT); /* OK to set the LFSBIT on a stack-cloned copy */
if (f.sizep) { /* clone included Protos */
Proto **p = luaM_newvector(L, f.sizep, Proto *);
for (i=0; i<f.sizep; i++)
p[i] = cast(Proto *, functionToFlash(L, f.p[i]));
f.p = cast(Proto **, flashCopy(L, f.sizep, "A", p));
luaM_freearray(L, p, f.sizep, Proto *);
}
f.k = cast(TValue *, flashCopy(L, f.sizek, "V", f.k));
f.code = cast(Instruction *, flashCopy(L, f.sizecode, "I", f.code));
#ifdef LUA_OPTIMIZE_DEBUG
if (f.packedlineinfo) {
TString *ts=luaS_new(L, cast(const char *,f.packedlineinfo));
f.packedlineinfo = cast(unsigned char *, resolveTString(L, ts)) + sizeof (FlashTS);
}
#else
f.lineinfo = cast(int *, flashCopy(L, f.sizelineinfo, "I", f.lineinfo));
#endif
f.locvars = cast(struct LocVar *, flashCopy(L, f.sizelocvars, "SII", f.locvars));
f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues));
return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f));
}
/*
* Scan through the tagged addresses. This operates in one of two modes.
* - If address is non-zero then the offset is converted back into an absolute
* mapped flash address using the specified address base.
*
* - If the address is zero then form a form linked chain with the upper 16 bits
* the link to the last offset. As the scan is backwards, this 'last' address
* becomes forward reference for the on-chip LFS loader.
*/
void linkAddresses(lu_int32 address){
int i, last = 0;
for (i = curOffset-1 ; i >= 0; i--) {
if (flashAddrTag[i]) {
lua_assert(flashImage[i]<curOffset);
if (address) {
flashImage[i] = 4*flashImage[i] + address;
} else {
flashImage[i] |= last<<16;
last = i;
}
}
}
}
uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
void* data, int strip, lu_int32 address) {
// parameter strip is ignored for now
lua_newtable(L);
FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader)));
scanProtoStrings(L, main);
createROstrt(L, fh);
toFlashAddr(L, fh->mainProto, functionToFlash(L, main));
fh->flash_sig = FLASH_SIG + (address ? FLASH_SIG_ABSOLUTE : 0);
fh->flash_size = curOffset*WORDSIZE;
linkAddresses(address);
lua_unlock(L);
int status = w(L, flashImage, curOffset * sizeof(uint), data);
lua_lock(L);
return status;
}
...@@ -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;
} }
...@@ -11,13 +11,14 @@ ...@@ -11,13 +11,14 @@
#include C_HEADER_STDIO #include C_HEADER_STDIO
#include C_HEADER_STDLIB #include C_HEADER_STDLIB
#include C_HEADER_STRING #include C_HEADER_STRING
#include <time.h>
#define luac_c #define luac_c
#define LUA_CORE #define LUA_CORE
#include "lua.h" #include "lua.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h"
#include "ldo.h" #include "ldo.h"
#include "lfunc.h" #include "lfunc.h"
#include "lmem.h" #include "lmem.h"
...@@ -32,16 +33,22 @@ ...@@ -32,16 +33,22 @@
static int listing=0; /* list bytecodes? */ static int listing=0; /* list bytecodes? */
static int dumping=1; /* dump bytecodes? */ static int dumping=1; /* dump bytecodes? */
static int stripping=0; /* strip debug information? */ static int stripping=0; /* strip debug information? */
static int flash=0; /* output flash image */
static lu_int32 address=0; /* output flash image at absolute location */
static int lookup=0; /* output lookup-style master combination header */
static char Output[]={ OUTPUT }; /* default output file name */ static char Output[]={ OUTPUT }; /* default output file name */
static const char* output=Output; /* actual output file name */ static const char* output=Output; /* actual output file name */
static const char* execute; /* executed a Lua file */
static const char* progname=PROGNAME; /* actual program name */ static const char* progname=PROGNAME; /* actual program name */
static DumpTargetInfo target; static DumpTargetInfo target;
static void fatal(const char* message) void luac_fatal(const char* message)
{ {
fprintf(stderr,"%s: %s\n",progname,message); fprintf(stderr,"%s: %s\n",progname,message);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#define fatal(s) luac_fatal(s)
static void cannot(const char* what) static void cannot(const char* what)
{ {
...@@ -61,18 +68,21 @@ static void usage(const char* message) ...@@ -61,18 +68,21 @@ static void usage(const char* message)
" - process stdin\n" " - process stdin\n"
" -l list\n" " -l list\n"
" -o name output to file " LUA_QL("name") " (default is \"%s\")\n" " -o name output to file " LUA_QL("name") " (default is \"%s\")\n"
" -e name execute a lua source file\n"
" -f output a flash image file\n"
" -a addr generate an absolute, rather than position independent flash image file\n"
" -i generate lookup combination master (default with option -f)\n"
" -p parse only\n" " -p parse only\n"
" -s strip debug information\n" " -s strip debug information\n"
" -v show version information\n" " -v show version information\n"
" -cci bits cross-compile with given integer size\n"
" -ccn type bits cross-compile with given lua_Number type and size\n"
" -cce endian cross-compile with given endianness ('big' or 'little')\n"
" -- stop handling options\n", " -- stop handling options\n",
progname,Output); progname,Output);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#define IS(s) (strcmp(argv[i],s)==0) #define IS(s) (strcmp(argv[i],s)==0)
#define IROM0_SEG 0x40210000ul
#define IROM0_SEGMAX 0x00100000ul
static int doargs(int argc, char* argv[]) static int doargs(int argc, char* argv[])
{ {
...@@ -91,6 +101,26 @@ static int doargs(int argc, char* argv[]) ...@@ -91,6 +101,26 @@ static int doargs(int argc, char* argv[])
} }
else if (IS("-")) /* end of options; use stdin */ else if (IS("-")) /* end of options; use stdin */
break; break;
else if (IS("-e")) /* execute a lua source file file */
{
execute=argv[++i];
if (execute ==NULL || *execute==0 || *execute=='-' )
usage(LUA_QL("-e") " needs argument");
}
else if (IS("-f")) /* Flash image file */
{
flash=lookup=1;
}
else if (IS("-a")) /* Absolue flash image file */
{
flash=lookup=1;
address=strtol(argv[++i],NULL,0);
size_t offset = (unsigned) (address -IROM0_SEG);
if (offset > IROM0_SEGMAX)
usage(LUA_QL("-e") " absolute address must be valid flash address");
}
else if (IS("-i")) /* lookup */
lookup = 1;
else if (IS("-l")) /* list */ else if (IS("-l")) /* list */
++listing; ++listing;
else if (IS("-o")) /* output file */ else if (IS("-o")) /* output file */
...@@ -99,42 +129,17 @@ static int doargs(int argc, char* argv[]) ...@@ -99,42 +129,17 @@ static int doargs(int argc, char* argv[])
if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument"); if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument");
if (IS("-")) output=NULL; if (IS("-")) output=NULL;
} }
else if (IS("-p")) /* parse only */ else if (IS("-p")) /* parse only */
dumping=0; dumping=0;
else if (IS("-s")) /* strip debug information */ else if (IS("-s")) /* strip debug information */
stripping=1; stripping=1;
else if (IS("-v")) /* show version */ else if (IS("-v")) /* show version */
++version; ++version;
else if (IS("-cci")) /* target integer size */
{
int s = target.sizeof_int = atoi(argv[++i])/8;
if (!(s==1 || s==2 || s==4)) fatal(LUA_QL("-cci") " must be 8, 16 or 32");
}
else if (IS("-ccn")) /* target lua_Number type and size */
{
const char *type=argv[++i];
if (strcmp(type,"int")==0) target.lua_Number_integral=1;
else if (strcmp(type,"float")==0) target.lua_Number_integral=0;
else if (strcmp(type,"float_arm")==0)
{
target.lua_Number_integral=0;
target.is_arm_fpa=1;
}
else fatal(LUA_QL("-ccn") " type must be " LUA_QL("int") " or " LUA_QL("float") " or " LUA_QL("float_arm"));
int s = target.sizeof_lua_Number = atoi(argv[++i])/8;
if (target.lua_Number_integral && !(s==1 || s==2 || s==4)) fatal(LUA_QL("-ccn") " size must be 8, 16, or 32 for int");
if (!target.lua_Number_integral && !(s==4 || s==8)) fatal(LUA_QL("-ccn") " size must be 32 or 64 for float");
}
else if (IS("-cce")) /* target endianness */
{
const char *val=argv[++i];
if (strcmp(val,"big")==0) target.little_endian=0;
else if (strcmp(val,"little")==0) target.little_endian=1;
else fatal(LUA_QL("-cce") " must be " LUA_QL("big") " or " LUA_QL("little"));
}
else /* unknown option */ else /* unknown option */
usage(argv[i]); usage(argv[i]);
} }
if (i==argc && (listing || !dumping)) if (i==argc && (listing || !dumping))
{ {
dumping=0; dumping=0;
...@@ -150,30 +155,99 @@ static int doargs(int argc, char* argv[]) ...@@ -150,30 +155,99 @@ static int doargs(int argc, char* argv[])
#define toproto(L,i) (clvalue(L->top+(i))->l.p) #define toproto(L,i) (clvalue(L->top+(i))->l.p)
static const Proto* combine(lua_State* L, int n) static TString *corename(lua_State *L, const TString *filename)
{ {
if (n==1) const char *fn = getstr(filename)+1;
const char *s = strrchr(fn, '/');
s = s ? s + 1 : fn;
while (*s == '.') s++;
const char *e = strchr(s, '.');
int l = e ? e - s: strlen(s);
return l ? luaS_newlstr (L, s, l) : luaS_new(L, fn);
}
/*
* If the luac command line includes multiple files or has the -f option
* then luac generates a main function to reference all sub-main prototypes.
* This is one of two types:
* Type 0 The standard luac combination main
* Type 1 A lookup wrapper that facilitates indexing into the generated protos
*/
static const Proto* combine(lua_State* L, int n, int type)
{
if (n==1 && type == 0)
return toproto(L,-1); return toproto(L,-1);
else else
{ {
int i,pc; int i;
Instruction *pc;
Proto* f=luaF_newproto(L); Proto* f=luaF_newproto(L);
setptvalue2s(L,L->top,f); incr_top(L); setptvalue2s(L,L->top,f); incr_top(L);
f->source=luaS_newliteral(L,"=(" PROGNAME ")"); f->source=luaS_newliteral(L,"=(" PROGNAME ")");
f->maxstacksize=1;
pc=2*n+1;
f->code=luaM_newvector(L,pc,Instruction);
f->sizecode=pc;
f->p=luaM_newvector(L,n,Proto*); f->p=luaM_newvector(L,n,Proto*);
f->sizep=n; f->sizep=n;
pc=0;
for (i=0; i<n; i++) for (i=0; i<n; i++)
{
f->p[i]=toproto(L,i-n-1); f->p[i]=toproto(L,i-n-1);
f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); pc=0;
f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1);
if (type == 0) {
/*
* Type 0 is as per the standard luac, which is just a main routine which
* invokes all of the compiled functions sequentially. This is fine if
* they are self registering modules, but useless otherwise.
*/
f->numparams = 0;
f->maxstacksize = 1;
f->sizecode = 2*n + 1 ;
f->sizek = 0;
f->code = luaM_newvector(L, f->sizecode , Instruction);
f->k = luaM_newvector(L,f->sizek,TValue);
for (i=0, pc = f->code; i<n; i++) {
*pc++ = CREATE_ABx(OP_CLOSURE,0,i);
*pc++ = CREATE_ABC(OP_CALL,0,1,1);
}
*pc++ = CREATE_ABC(OP_RETURN,0,1,0);
} else {
/*
* The Type 1 main() is a lookup which takes a single argument, the name to
* be resolved. If this matches root name of one of the compiled files then
* a closure to this file main is returned. Otherwise the Unixtime of the
* compile and the list of root names is returned.
*/
if (n > LFIELDS_PER_FLUSH) {
#define NO_MOD_ERR_(n) ": Number of modules > " #n
#define NO_MOD_ERR(n) NO_MOD_ERR_(n)
usage(LUA_QL("-f") NO_MOD_ERR(LFIELDS_PER_FLUSH));
} }
f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); f->numparams = 1;
f->maxstacksize = n + 3;
f->sizecode = 5*n + 5 ;
f->sizek = n + 1;
f->sizelocvars = 0;
f->code = luaM_newvector(L, f->sizecode , Instruction);
f->k = luaM_newvector(L,f->sizek,TValue);
for (i=0, pc = f->code; i<n; i++)
{
/* if arg1 == FnameA then return function (...) -- funcA -- end end */
setsvalue2n(L,f->k+i,corename(L, f->p[i]->source));
*pc++ = CREATE_ABC(OP_EQ,0,0,RKASK(i));
*pc++ = CREATE_ABx(OP_JMP,0,MAXARG_sBx+2);
*pc++ = CREATE_ABx(OP_CLOSURE,1,i);
*pc++ = CREATE_ABC(OP_RETURN,1,2,0);
}
setnvalue(f->k+n, (lua_Number) time(NULL));
*pc++ = CREATE_ABx(OP_LOADK,1,n);
*pc++ = CREATE_ABC(OP_NEWTABLE,2,luaO_int2fb(i),0);
for (i=0; i<n; i++)
*pc++ = CREATE_ABx(OP_LOADK,i+3,i);
*pc++ = CREATE_ABC(OP_SETLIST,2,i,1);
*pc++ = CREATE_ABC(OP_RETURN,1,3,0);
*pc++ = CREATE_ABC(OP_RETURN,0,1,0);
}
lua_assert((pc-f->code) == f->sizecode);
return f; return f;
} }
} }
...@@ -189,6 +263,9 @@ struct Smain { ...@@ -189,6 +263,9 @@ struct Smain {
char** argv; char** argv;
}; };
extern uint dumpToFlashImage (lua_State* L,const Proto *main, lua_Writer w,
void* data, int strip, lu_int32 address);
static int pmain(lua_State* L) static int pmain(lua_State* L)
{ {
struct Smain* s = (struct Smain*)lua_touserdata(L, 1); struct Smain* s = (struct Smain*)lua_touserdata(L, 1);
...@@ -197,19 +274,39 @@ static int pmain(lua_State* L) ...@@ -197,19 +274,39 @@ static int pmain(lua_State* L)
const Proto* f; const Proto* f;
int i; int i;
if (!lua_checkstack(L,argc)) fatal("too many input files"); if (!lua_checkstack(L,argc)) fatal("too many input files");
if (execute)
{
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
luaL_openlibs(L);
lua_pushstring(L, execute);
if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
if (!lua_isfunction(L, -1))
{
lua_pop(L,1);
if(argc == 0) return 0;
execute = NULL;
}
}
for (i=0; i<argc; i++) for (i=0; i<argc; i++)
{ {
const char* filename=IS("-") ? NULL : argv[i]; const char* filename=IS("-") ? NULL : argv[i];
if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1)); if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1));
} }
f=combine(L,argc); f=combine(L,argc + (execute ? 1: 0), lookup);
if (listing) luaU_print(f,listing>1); if (listing) luaU_print(f,listing>1);
if (dumping) if (dumping)
{ {
int result;
FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); FILE* D= (output==NULL) ? stdout : fopen(output,"wb");
if (D==NULL) cannot("open"); if (D==NULL) cannot("open");
lua_lock(L); lua_lock(L);
int result=luaU_dump_crosscompile(L,f,writer,D,stripping,target); if (flash)
{
result=dumpToFlashImage(L,f,writer, D, stripping, address);
} else
{
result=luaU_dump_crosscompile(L,f,writer,D,stripping,target);
}
lua_unlock(L); lua_unlock(L);
if (result==LUA_ERR_CC_INTOVERFLOW) fatal("value too big or small for target integer type"); if (result==LUA_ERR_CC_INTOVERFLOW) fatal("value too big or small for target integer type");
if (result==LUA_ERR_CC_NOTINTEGER) fatal("target lua_Number is integral but fractional value found"); if (result==LUA_ERR_CC_NOTINTEGER) fatal("target lua_Number is integral but fractional value found");
...@@ -234,7 +331,7 @@ int main(int argc, char* argv[]) ...@@ -234,7 +331,7 @@ int main(int argc, char* argv[])
int i=doargs(argc,argv); int i=doargs(argc,argv);
argc-=i; argv+=i; argc-=i; argv+=i;
if (argc<=0) usage("no input files given"); if (argc<=0 && execute==0) usage("no input files given");
L=lua_open(); L=lua_open();
if (L==NULL) fatal("not enough memory for state"); if (L==NULL) fatal("not enough memory for state");
s.argc=argc; s.argc=argc;
......
...@@ -38,6 +38,11 @@ ...@@ -38,6 +38,11 @@
#define LUA_WIN #define LUA_WIN
#endif #endif
#if defined(LUA_CROSS_COMPILER)
#define LUA_USE_LINUX
#endif
#if defined(LUA_USE_LINUX) #if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX #define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ #define LUA_USE_DLOPEN /* needs an extra library: -ldl */
...@@ -59,7 +64,7 @@ ...@@ -59,7 +64,7 @@
#if defined(LUA_USE_POSIX) #if defined(LUA_USE_POSIX)
#define LUA_USE_MKSTEMP #define LUA_USE_MKSTEMP
#define LUA_USE_ISATTY #define LUA_USE_ISATTY
#define LUA_USE_POPEN //#define LUA_USE_POPEN
#define LUA_USE_ULONGJMP #define LUA_USE_ULONGJMP
#endif #endif
...@@ -167,7 +172,7 @@ ...@@ -167,7 +172,7 @@
#define LUA_INTEGER ptrdiff_t #define LUA_INTEGER ptrdiff_t
#else #else
#if !defined LUA_INTEGRAL_LONGLONG #if !defined LUA_INTEGRAL_LONGLONG
#define LUA_INTEGER long #define LUA_INTEGER int
#else #else
#define LUA_INTEGER long long #define LUA_INTEGER long long
#endif // #if !defined LUA_INTEGRAL_LONGLONG #endif // #if !defined LUA_INTEGRAL_LONGLONG
...@@ -487,7 +492,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length); ...@@ -487,7 +492,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
/* 16-bit ints */ /* 16-bit ints */
#define LUAI_UINT32 unsigned long #define LUAI_UINT32 unsigned long
#define LUAI_INT32 long #define LUAI_INT32 long
#define LUAI_MAXINT32 LONG_MAX #define LUAI_MAXINT32 INT_MAX
#define LUAI_UMEM unsigned long #define LUAI_UMEM unsigned long
#define LUAI_MEM long #define LUAI_MEM long
#endif #endif
...@@ -607,8 +612,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length); ...@@ -607,8 +612,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
*/ */
#if defined LUA_NUMBER_INTEGRAL #if defined LUA_NUMBER_INTEGRAL
#if !defined LUA_INTEGRAL_LONGLONG #if !defined LUA_INTEGRAL_LONGLONG
#define LUA_NUMBER_SCAN "%ld" #define LUA_NUMBER_SCAN "%d"
#define LUA_NUMBER_FMT "%ld" #define LUA_NUMBER_FMT "%d"
#else #else
#define LUA_NUMBER_SCAN "%lld" #define LUA_NUMBER_SCAN "%lld"
#define LUA_NUMBER_FMT "%lld" #define LUA_NUMBER_FMT "%lld"
...@@ -894,7 +899,7 @@ union luai_Cast { double l_d; long l_l; }; ...@@ -894,7 +899,7 @@ union luai_Cast { double l_d; long l_l; };
/* If you define the next macro you'll get the ability to set rotables as /* If you define the next macro you'll get the ability to set rotables as
metatables for tables/userdata/types (but the VM might run slower) metatables for tables/userdata/types (but the VM might run slower)
*/ */
#if (LUA_OPTIMIZE_MEMORY == 2) && !defined(LUA_CROSS_COMPILER) #if (LUA_OPTIMIZE_MEMORY == 2)
#define LUA_META_ROTABLES #define LUA_META_ROTABLES
#endif #endif
......
...@@ -172,7 +172,7 @@ static TString* LoadString(LoadState* S) ...@@ -172,7 +172,7 @@ static TString* LoadString(LoadState* S)
} else { } else {
s = (char*)luaZ_get_crt_address(S->Z); s = (char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,size); LoadBlock(S,NULL,size);
return luaS_newrolstr(S->L,s,size-1); return luaS_newlstr(S->L,s,size-1);
} }
} }
} }
...@@ -280,7 +280,7 @@ static Proto* LoadFunction(LoadState* S, TString* p) ...@@ -280,7 +280,7 @@ static Proto* LoadFunction(LoadState* S, TString* p)
Proto* f; Proto* f;
if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
f=luaF_newproto(S->L); f=luaF_newproto(S->L);
if (luaZ_direct_mode(S->Z)) proto_readonly(f); if (luaZ_direct_mode(S->Z)) l_setbit((f)->marked, READONLYBIT);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p; f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S); f->linedefined=LoadInt(S);
......
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