Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
27a83feb
Unverified
Commit
27a83feb
authored
Jun 29, 2018
by
Terry Ellison
Committed by
GitHub
Jun 29, 2018
Browse files
Merge pull request #2301 from TerryE/dev-LFS
LFS evaluation version -- second release
parents
2cc195d5
a3c2f48f
Changes
92
Show whitespace changes
Inline
Side-by-side
app/lua/lrotable.c
View file @
27a83feb
...
...
@@ -14,7 +14,7 @@
#define LUAR_FINDVALUE 1
/* Externally defined read-only table array */
extern
const
luaR_table
lua_rotable
[]
;
extern
const
luaR_table
*
lua_rotable
;
/* Find a global "read only table" in the constant lua_rotable array */
void
*
luaR_findglobal
(
const
char
*
name
,
unsigned
len
)
{
...
...
@@ -85,7 +85,7 @@ static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos,
if
(
pentries
[
pos
].
key
.
type
!=
LUA_TNIL
)
{
/* Found an entry */
if
(
pentries
[
pos
].
key
.
type
==
LUA_TSTRING
)
setsvalue
(
L
,
key
,
luaS_new
ro
(
L
,
pentries
[
pos
].
key
.
id
.
strkey
))
setsvalue
(
L
,
key
,
luaS_new
(
L
,
pentries
[
pos
].
key
.
id
.
strkey
))
else
setnvalue
(
key
,
(
lua_Number
)
pentries
[
pos
].
key
.
id
.
numkey
)
setobj2s
(
L
,
val
,
&
pentries
[
pos
].
value
);
...
...
@@ -127,10 +127,15 @@ void luaR_getcstr(char *dest, const TString *src, size_t maxsize) {
/* Return 1 if the given pointer is a rotable */
#ifdef LUA_META_ROTABLES
#ifdef LUA_CROSS_COMPILER
extern
char
edata
[];
int
luaR_isrotable
(
void
*
p
)
{
return
(
char
*
)
p
<=
edata
;
}
#else
#include "compiler.h"
int
luaR_isrotable
(
void
*
p
)
{
return
RODATA_START_ADDRESS
<=
(
char
*
)
p
&&
(
char
*
)
p
<=
RODATA_END_ADDRESS
;
}
#endif
#endif
app/lua/lrotable.h
View file @
27a83feb
...
...
@@ -4,32 +4,16 @@
#define lrotable_h
#include "lua.h"
#include "llimits.h"
#include "lobject.h"
#include "luaconf.h"
#include "lobject.h"
#include "llimits.h"
/* Macros one can use to define rotable entries */
#ifndef LUA_PACK_VALUE
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_LUDATA(v) {{.p = v}, LUA_TLIGHTUSERDATA}
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#else // #ifndef LUA_PACK_VALUE
#define LRO_NUMVAL(v) {.value.n = v}
#ifdef ELUA_ENDIAN_LITTLE
#define LRO_FUNCVAL(v) {{(int)v, add_sig(LUA_TLIGHTFUNCTION)}}
#define LRO_LUDATA(v) {{(int)v, add_sig(LUA_TLIGHTUSERDATA)}}
#define LRO_ROVAL(v) {{(int)v, add_sig(LUA_TROTABLE)}}
#define LRO_NILVAL {{0, add_sig(LUA_TNIL)}}
#else // #ifdef ELUA_ENDIAN_LITTLE
#define LRO_FUNCVAL(v) {{add_sig(LUA_TLIGHTFUNCTION), (int)v}}
#define LRO_LUDATA(v) {{add_sig(LUA_TLIGHTUSERDATA), (int)v}}
#define LRO_ROVAL(v) {{add_sig(LUA_TROTABLE), (int)v}}
#define LRO_NILVAL {{add_sig(LUA_TNIL), 0}}
#endif // #ifdef ELUA_ENDIAN_LITTLE
#endif // #ifndef LUA_PACK_VALUE
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
...
...
app/lua/lstate.c
View file @
27a83feb
...
...
@@ -13,6 +13,7 @@
#include "ldebug.h"
#include "ldo.h"
#include "lflash.h"
#include "lfunc.h"
#include "lgc.h"
#include "llex.h"
...
...
@@ -72,9 +73,12 @@ static void f_luaopen (lua_State *L, void *ud) {
sethvalue
(
L
,
gt
(
L
),
luaH_new
(
L
,
0
,
2
));
/* table of globals */
sethvalue
(
L
,
registry
(
L
),
luaH_new
(
L
,
0
,
2
));
/* registry */
luaS_resize
(
L
,
MINSTRTABSIZE
);
/* initial size of string table */
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
luaN_init
(
L
);
/* optionally map RO string table */
#endif
luaT_init
(
L
);
luaX_init
(
L
);
luaS_
fix
(
luaS_newliteral
(
L
,
MEMERRMSG
));
string
fix
(
luaS_newliteral
(
L
,
MEMERRMSG
));
g
->
GCthreshold
=
4
*
g
->
totalbytes
;
}
...
...
@@ -191,6 +195,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g
->
memlimit
=
EGC_INITIAL_MEMLIMIT
;
#else
g
->
memlimit
=
0
;
#endif
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
g
->
ROstrt
.
size
=
0
;
g
->
ROstrt
.
nuse
=
0
;
g
->
ROstrt
.
hash
=
NULL
;
g
->
ROpvmain
=
NULL
;
#endif
for
(
i
=
0
;
i
<
NUM_TAGS
;
i
++
)
g
->
mt
[
i
]
=
NULL
;
if
(
luaD_rawrunprotected
(
L
,
f_luaopen
,
NULL
)
!=
0
)
{
...
...
app/lua/lstate.h
View file @
27a83feb
...
...
@@ -94,6 +94,10 @@ typedef struct global_State {
UpVal
uvhead
;
/* head of double-linked list of all open upvalues */
struct
Table
*
mt
[
NUM_TAGS
];
/* metatables for basic types */
TString
*
tmname
[
TM_N
];
/* array with tag-method names */
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
stringtable
ROstrt
;
/* Flash-based hash table for RO strings */
Proto
*
ROpvmain
;
/* Flash-based Proto main */
#endif
}
global_State
;
...
...
app/lua/lstring.c
View file @
27a83feb
...
...
@@ -61,7 +61,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
tb
=
&
G
(
L
)
->
strt
;
if
((
tb
->
nuse
+
1
)
>
cast
(
lu_int32
,
tb
->
size
)
&&
tb
->
size
<=
MAX_INT
/
2
)
luaS_resize
(
L
,
tb
->
size
*
2
);
/* too crowded */
ts
=
cast
(
TString
*
,
luaM_malloc
(
L
,
readonly
?
sizeof
(
char
**
)
+
sizeof
(
TString
)
:
(
l
+
1
)
*
sizeof
(
char
)
+
sizeof
(
TString
)));
ts
=
cast
(
TString
*
,
luaM_malloc
(
L
,
sizeof
(
TString
)
+
(
readonly
?
sizeof
(
char
**
)
:
(
l
+
1
)
*
sizeof
(
char
))));
ts
->
tsv
.
len
=
l
;
ts
->
tsv
.
hash
=
h
;
ts
->
tsv
.
marked
=
luaC_white
(
G
(
L
));
...
...
@@ -71,7 +71,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
((
char
*
)(
ts
+
1
))[
l
]
=
'\0'
;
/* ending 0 */
}
else
{
*
(
char
**
)(
ts
+
1
)
=
(
char
*
)
str
;
l
uaS_readonly
(
ts
);
l
_setbit
((
ts
)
->
tsv
.
marked
,
READONLYBIT
);
}
h
=
lmod
(
h
,
tb
->
size
);
ts
->
tsv
.
next
=
tb
->
hash
[
h
];
/* chain new entry */
...
...
@@ -80,14 +80,29 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
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
;
unsigned
int
h
=
cast
(
unsigned
int
,
l
);
/* seed */
size_t
step
=
(
l
>>
5
)
+
1
;
/* if string is too long, don't hash all its chars */
size_t
l1
;
for
(
l1
=
l
;
l1
>=
step
;
l1
-=
step
)
/* compute hash */
h
=
h
^
((
h
<<
5
)
+
(
h
>>
2
)
+
cast
(
unsigned
char
,
str
[
l1
-
1
]));
for
(
o
=
G
(
L
)
->
strt
.
hash
[
lmod
(
h
,
G
(
L
)
->
strt
.
size
)];
o
!=
NULL
;
o
=
o
->
gch
.
next
)
{
...
...
@@ -98,35 +113,27 @@ static TString *luaS_newlstr_helper (lua_State *L, const char *str, size_t l, in
return
ts
;
}
}
return
newlstr
(
L
,
str
,
l
,
h
,
readonly
);
/* not found */
}
static
int
lua_is_ptr_in_ro_area
(
const
char
*
p
)
{
#ifdef LUA_CROSS_COMPILER
return
0
;
#else
#include "compiler.h"
return
p
>=
RODATA_START_ADDRESS
&&
p
<=
RODATA_END_ADDRESS
;
#if defined(LUA_FLASH_STORE) && !defined(LUA_CROSS_COMPILER)
/*
* The RAM strt is searched first since RAM access is faster tham Flash access.
* If a miss, then search the RO string table.
*/
if
(
G
(
L
)
->
ROstrt
.
hash
)
{
for
(
o
=
G
(
L
)
->
ROstrt
.
hash
[
lmod
(
h
,
G
(
L
)
->
ROstrt
.
size
)];
o
!=
NULL
;
o
=
o
->
gch
.
next
)
{
TString
*
ts
=
rawgco2ts
(
o
);
if
(
ts
->
tsv
.
len
==
l
&&
(
memcmp
(
str
,
getstr
(
ts
),
l
)
==
0
))
{
return
ts
;
}
}
}
#endif
}
TString
*
luaS_newlstr
(
lua_State
*
L
,
const
char
*
str
,
size_t
l
)
{
// If the pointer is in a read-only memory and the string is at least 4 chars in length,
// create it as a read-only string instead
if
(
lua_is_ptr_in_ro_area
(
str
)
&&
l
+
1
>
sizeof
(
char
**
)
&&
l
==
c_strlen
(
str
))
return
luaS_newlstr_helper
(
L
,
str
,
l
,
LUAS_READONLY_STRING
);
else
return
luaS_newlstr_helper
(
L
,
str
,
l
,
LUAS_REGULAR_STRING
);
}
LUAI_FUNC
TString
*
luaS_newrolstr
(
lua_State
*
L
,
const
char
*
str
,
size_t
l
)
{
if
(
l
+
1
>
sizeof
(
char
**
)
&&
l
==
c_strlen
(
str
))
return
luaS_newlstr_helper
(
L
,
str
,
l
,
LUAS_READONLY_STRING
);
else
// no point in creating a RO string, as it would actually be larger
return
luaS_newlstr_helper
(
L
,
str
,
l
,
LUAS_REGULAR_STRING
);
/* New additions to the RAM strt are tagged as readonly if the string address
* is in the CTEXT segment (target only, not luac.cross) */
int
readonly
=
(
lua_is_ptr_in_ro_area
(
str
)
&&
l
+
1
>
sizeof
(
char
**
)
&&
l
==
c_strlen
(
str
)
?
LUAS_READONLY_STRING
:
LUAS_REGULAR_STRING
);
return
newlstr
(
L
,
str
,
l
,
h
,
readonly
);
/* not found */
}
...
...
app/lua/lstring.h
View file @
27a83feb
...
...
@@ -13,22 +13,16 @@
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+(
luaS_isreadonly(s
) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizestring(s) (sizeof(union TString)+(
testbit((s)->marked, READONLYBIT
) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_new(L, s) (luaS_newlstr(L, s, c_strlen(s)))
#define luaS_newro(L, s) (luaS_newrolstr(L, s, c_strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
#define luaS_readonly(s) l_setbit((s)->tsv.marked, READONLYBIT)
#define luaS_isreadonly(s) testbit((s)->marked, READONLYBIT)
LUAI_FUNC
void
luaS_resize
(
lua_State
*
L
,
int
newsize
);
LUAI_FUNC
Udata
*
luaS_newudata
(
lua_State
*
L
,
size_t
s
,
Table
*
e
);
LUAI_FUNC
TString
*
luaS_newlstr
(
lua_State
*
L
,
const
char
*
str
,
size_t
l
);
LUAI_FUNC
TString
*
luaS_newrolstr
(
lua_State
*
L
,
const
char
*
str
,
size_t
l
);
#endif
app/lua/ltable.c
View file @
27a83feb
...
...
@@ -445,6 +445,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int
oldasize
=
t
->
sizearray
;
if
(
nasize
>
oldasize
)
/* array part must grow? */
setarrayvector
(
L
,
t
,
nasize
);
if
(
t
->
node
!=
dummynode
||
nhsize
>
0
)
resize_hashpart
(
L
,
t
,
nhsize
);
if
(
nasize
<
oldasize
)
{
/* array part must shrink? */
t
->
sizearray
=
nasize
;
...
...
@@ -749,12 +750,12 @@ int luaH_getn_ro (void *t) {
return
len
;
}
#if defined(LUA_DEBUG)
int
luaH_isdummy
(
Node
*
n
)
{
return
n
==
dummynode
;
}
#if defined(LUA_DEBUG)
Node
*
luaH_mainposition
(
const
Table
*
t
,
const
TValue
*
key
)
{
return
mainposition
(
t
,
key
);
}
#endif
int
luaH_isdummy
(
Node
*
n
)
{
return
n
==
dummynode
;
}
#endif
app/lua/ltable.h
View file @
27a83feb
...
...
@@ -34,11 +34,9 @@ LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC
int
luaH_next_ro
(
lua_State
*
L
,
void
*
t
,
StkId
key
);
LUAI_FUNC
int
luaH_getn
(
Table
*
t
);
LUAI_FUNC
int
luaH_getn_ro
(
void
*
t
);
LUAI_FUNC
int
luaH_isdummy
(
Node
*
n
);
#if defined(LUA_DEBUG)
LUAI_FUNC
Node
*
luaH_mainposition
(
const
Table
*
t
,
const
TValue
*
key
);
LUAI_FUNC
int
luaH_isdummy
(
Node
*
n
);
#endif
#endif
app/lua/ltablib.c
View file @
27a83feb
app/lua/ltm.c
View file @
27a83feb
...
...
@@ -14,6 +14,7 @@
#include "lobject.h"
#include "lstate.h"
#include "lgc.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
...
...
@@ -39,7 +40,7 @@ void luaT_init (lua_State *L) {
int
i
;
for
(
i
=
0
;
i
<
TM_N
;
i
++
)
{
G
(
L
)
->
tmname
[
i
]
=
luaS_new
(
L
,
luaT_eventname
[
i
]);
luaS_
fix
(
G
(
L
)
->
tmname
[
i
]);
/* never collect these names */
string
fix
(
G
(
L
)
->
tmname
[
i
]);
/* never collect these names */
}
}
...
...
app/lua/lua.c
View file @
27a83feb
...
...
@@ -13,6 +13,7 @@
#include "user_version.h"
#include "driver/readline.h"
#include "driver/uart.h"
#include "platform.h"
#define lua_c
...
...
@@ -21,54 +22,16 @@
#include "lauxlib.h"
#include "lualib.h"
#include "legc.h"
#ifdef LUA_FLASH_STORE
#include "lflash.h"
#endif
#include "os_type.h"
lua_State
*
globalL
=
NULL
;
lua_Load
gLoad
;
static
lua_Load
gLoad
;
static
const
char
*
progname
=
LUA_PROGNAME
;
#if 0
static void lstop (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0);
luaL_error(L, "interrupted!");
}
static void laction (int i) {
// signal(i, SIG_DFL);
/* if another SIGINT happens before lstop,
terminate process (default action) */
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void print_usage (void) {
#if defined(LUA_USE_STDIO)
c_fprintf(c_stderr,
#else
luai_writestringerror(
#endif
"usage: %s [options] [script [args]].
\n
"
"Available options are:
\n
"
" -e stat execute string "
LUA_QL
(
"stat"
)
"
\n
"
" -l name require library "
LUA_QL
(
"name"
)
"
\n
"
" -m limit set memory limit. (units are in Kbytes)
\n
"
" -i enter interactive mode after executing "
LUA_QL
(
"script"
)
"
\n
"
" -v show version information
\n
"
" -- stop handling options
\n
"
" - execute stdin and stop handling options
\n
"
,
progname
);
#if defined(LUA_USE_STDIO)
c_fflush
(
c_stderr
);
#endif
}
#endif
static
void
l_message
(
const
char
*
pname
,
const
char
*
msg
)
{
#if defined(LUA_USE_STDIO)
if
(
pname
)
c_fprintf
(
c_stderr
,
"%s: "
,
pname
);
...
...
@@ -154,17 +117,11 @@ static int getargs (lua_State *L, char **argv, int n) {
return
narg
;
}
#if 0
static int dofile (lua_State *L, const char *name) {
int status = luaL_loadfile(L, name) || docall(L, 0, 1);
return report(L, status);
}
#else
static
int
dofsfile
(
lua_State
*
L
,
const
char
*
name
)
{
int
status
=
luaL_loadfsfile
(
L
,
name
)
||
docall
(
L
,
0
,
1
);
return
report
(
L
,
status
);
}
#endif
static
int
dostring
(
lua_State
*
L
,
const
char
*
s
,
const
char
*
name
)
{
int
status
=
luaL_loadbuffer
(
L
,
s
,
c_strlen
(
s
),
name
)
||
docall
(
L
,
0
,
1
);
...
...
@@ -201,92 +158,6 @@ static int incomplete (lua_State *L, int status) {
return
0
;
/* else... */
}
#if 0
static int pushline (lua_State *L, int firstline) {
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
if (lua_readline(L, b, prmt) == 0)
return 0; /* no input */
l = c_strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[l-1] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* first line starts with `=' ? */
lua_pushfstring(L, "return %s", b+1); /* change it to `return' */
else
lua_pushstring(L, b);
lua_freeline(L, b);
return 1;
}
static int loadline (lua_State *L) {
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
for (;;) { /* repeat until gets a complete line */
status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin");
if (!incomplete(L, status)) break; /* cannot try to add lines? */
if (!pushline(L, 0)) /* no more input? */
return -1;
lua_pushliteral(L, "\n"); /* add a new line... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
}
lua_saveline(L, 1);
lua_remove(L, 1); /* remove line */
return status;
}
static void dotty (lua_State *L) {
int status;
const char *oldprogname = progname;
progname = NULL;
while ((status = loadline(L)) != -1) {
if (status == 0) status = docall(L, 0, 0);
report(L, status);
if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, lua_pushfstring(L,
"error calling " LUA_QL("print") " (%s)",
lua_tostring(L, -1)));
}
}
lua_settop(L, 0); /* clear stack */
#if defined(LUA_USE_STDIO)
c_fputs("\n", c_stdout);
c_fflush(c_stdout);
#else
luai_writeline();
#endif
progname
=
oldprogname
;
}
static
int
handle_script
(
lua_State
*
L
,
char
**
argv
,
int
n
)
{
int
status
;
const
char
*
fname
;
int
narg
=
getargs
(
L
,
argv
,
n
);
/* collect arguments */
lua_setglobal
(
L
,
"arg"
);
fname
=
argv
[
n
];
if
(
c_strcmp
(
fname
,
"-"
)
==
0
&&
c_strcmp
(
argv
[
n
-
1
],
"--"
)
!=
0
)
fname
=
NULL
;
/* stdin */
status
=
luaL_loadfile
(
L
,
fname
);
lua_insert
(
L
,
-
(
narg
+
1
));
if
(
status
==
0
)
status
=
docall
(
L
,
narg
,
0
);
else
lua_pop
(
L
,
narg
);
return
report
(
L
,
status
);
}
#endif
/* check that argument has no extra characters at the end */
#define notail(x) {if ((x)[2] != '\0') return -1;}
...
...
@@ -364,17 +235,16 @@ static int runargs (lua_State *L, char **argv, int n) {
}
#ifndef LUA_INIT_STRING
#define LUA_INIT_STRING "@init.lua"
#endif
static
int
handle_luainit
(
lua_State
*
L
)
{
const
char
*
init
=
c_getenv
(
LUA_INIT
);
if
(
init
==
NULL
)
return
0
;
/* status OK */
else
if
(
init
[
0
]
==
'@'
)
#if 0
return dofile(L, init+1);
#else
const
char
*
init
=
LUA_INIT_STRING
;
if
(
init
[
0
]
==
'@'
)
return
dofsfile
(
L
,
init
+
1
);
#endif
else
return
dostring
(
L
,
init
,
"="
LUA_INIT
);
return
dostring
(
L
,
init
,
LUA_INIT
);
}
...
...
@@ -397,40 +267,18 @@ static int pmain (lua_State *L) {
lua_gc
(
L
,
LUA_GCRESTART
,
0
);
print_version
(
L
);
s
->
status
=
handle_luainit
(
L
);
#if 0
if (s->status != 0) return 0;
#endif
script
=
collectargs
(
argv
,
&
has_i
,
&
has_v
,
&
has_e
);
if
(
script
<
0
)
{
/* invalid args? */
#if 0
print_usage();
#endif
s
->
status
=
1
;
return
0
;
}
// if (has_v) print_version();
s
->
status
=
runargs
(
L
,
argv
,
(
script
>
0
)
?
script
:
s
->
argc
);
if
(
s
->
status
!=
0
)
return
0
;
#if 0
if (script)
s->status = handle_script(L, argv, script);
if (s->status != 0) return 0;
if (has_i)
dotty(L);
else if (script == 0 && !has_e && !has_v) {
if (lua_stdin_is_tty()) {
print_version();
dotty(L);
}
else dofile(L, NULL); /* executes stdin as a file */
}
#endif
return
0
;
}
static
void
dojob
(
lua_Load
*
load
);
static
bool
readline
(
lua_Load
*
load
);
char
line_buffer
[
LUA_MAXINPUT
];
#ifdef LUA_RPC
int
main
(
int
argc
,
char
**
argv
)
{
...
...
@@ -439,6 +287,13 @@ int lua_main (int argc, char **argv) {
#endif
int
status
;
struct
Smain
s
;
#if defined(NODE_DEBUG) && defined(DEVELOPMENT_USE_GDB) && \
defined(DEVELOPMENT_BREAK_ON_STARTUP_PIN) && DEVELOPMENT_BREAK_ON_STARTUP_PIN > 0
platform_gpio_mode
(
DEVELOPMENT_BREAK_ON_STARTUP_PIN
,
PLATFORM_GPIO_INPUT
,
PLATFORM_GPIO_PULLUP
);
lua_assert
(
platform_gpio_read
(
DEVELOPMENT_BREAK_ON_STARTUP_PIN
));
// Break if pin pulled low
#endif
lua_State
*
L
=
lua_open
();
/* create state */
if
(
L
==
NULL
)
{
l_message
(
argv
[
0
],
"cannot create state: not enough memory"
);
...
...
@@ -446,30 +301,44 @@ int lua_main (int argc, char **argv) {
}
s
.
argc
=
argc
;
s
.
argv
=
argv
;
status
=
lua_cpcall
(
L
,
&
pmain
,
&
s
);
report
(
L
,
status
);
gLoad
.
L
=
L
;
gLoad
.
firstline
=
1
;
gLoad
.
done
=
0
;
gLoad
.
line
=
line_buffer
;
gLoad
.
line
=
c_malloc
(
LUA_MAXINPUT
)
;
gLoad
.
len
=
LUA_MAXINPUT
;
gLoad
.
line_position
=
0
;
gLoad
.
prmt
=
get_prompt
(
L
,
1
);
dojob
(
&
gLoad
);
NODE_DBG
(
"Heap size:
:
%d.
\n
"
,
system_get_free_heap_size
());
NODE_DBG
(
"Heap size:%d.
\n
"
,
system_get_free_heap_size
());
legc_set_mode
(
L
,
EGC_ALWAYS
,
4096
);
// legc_set_mode( L, EGC_ON_MEM_LIMIT, 4096 );
// lua_close(L);
return
(
status
||
s
.
status
)
?
EXIT_FAILURE
:
EXIT_SUCCESS
;
}
int
lua_put_line
(
const
char
*
s
,
size_t
l
)
{
if
(
s
==
NULL
||
++
l
<
LUA_MAXINPUT
||
gLoad
.
line_position
>
0
)
return
0
;
c_memcpy
(
gLoad
.
line
,
s
,
l
);
gLoad
.
line
[
l
]
=
'\0'
;
gLoad
.
line_position
=
l
;
gLoad
.
done
=
1
;
NODE_DBG
(
"Get command: %s
\n
"
,
gLoad
.
line
);
return
1
;
}
void
lua_handle_input
(
bool
force
)
{
while
(
gLoad
.
L
&&
(
force
||
readline
(
&
gLoad
)))
{
while
(
gLoad
.
L
&&
(
force
||
readline
(
&
gLoad
)))
{
NODE_DBG
(
"Handle Input: first=%u, pos=%u, len=%u, actual=%u, line=%s
\n
"
,
gLoad
.
firstline
,
gLoad
.
line_position
,
gLoad
.
len
,
c_strlen
(
gLoad
.
line
),
gLoad
.
line
);
dojob
(
&
gLoad
);
force
=
false
;
}
...
...
app/lua/lua.h
View file @
27a83feb
...
...
@@ -173,7 +173,6 @@ LUA_API void (lua_pushnil) (lua_State *L);
LUA_API
void
(
lua_pushnumber
)
(
lua_State
*
L
,
lua_Number
n
);
LUA_API
void
(
lua_pushinteger
)
(
lua_State
*
L
,
lua_Integer
n
);
LUA_API
void
(
lua_pushlstring
)
(
lua_State
*
L
,
const
char
*
s
,
size_t
l
);
LUA_API
void
(
lua_pushrolstring
)
(
lua_State
*
L
,
const
char
*
s
,
size_t
l
);
LUA_API
void
(
lua_pushstring
)
(
lua_State
*
L
,
const
char
*
s
);
LUA_API
const
char
*
(
lua_pushvfstring
)
(
lua_State
*
L
,
const
char
*
fmt
,
va_list
argp
);
...
...
app/lua/luac_cross.h
View file @
27a83feb
...
...
@@ -31,6 +31,7 @@
#define c_freopen freopen
#define c_getc getc
#define c_getenv getenv
#define c_malloc malloc
#define c_memcmp memcmp
#define c_memcpy memcpy
#define c_printf printf
...
...
@@ -56,9 +57,10 @@
#define c_strrchr strrchr
#define c_strstr strstr
double
c_strtod
(
const
char
*
__n
,
char
**
__end_PTR
);
#define c_strtoul strtoul
#define c_ungetc ungetc
#define c_strtol strtol
#define c_strtoul strtoul
#define dbg_printf printf
#else
#define C_HEADER_ASSERT "c_assert.h"
...
...
app/lua/luac_cross/Makefile
0 → 100644
View file @
27a83feb
#
# 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
$@
.
$$$$
app/lua/luac_cross/lflashimg.c
0 → 100644
View file @
27a83feb
/*
** 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
;
}
app/lua/liolib.c
→
app/lua/
luac_cross/
liolib.c
View file @
27a83feb
...
...
@@ -5,14 +5,14 @@
*/
// #include "c_errno.h"
#include "c_stdio.h"
#include "c_stdlib.h"
#include "c_string.h"
#include "vfs.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define liolib_c
#define LUA_LIB
#define LUA_OPTIMIZE_MEMORY 2
#include "lua.h"
...
...
@@ -20,26 +20,21 @@
#include "lualib.h"
#include "lrotable.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
#define IO_STDERR 0
#if LUA_OPTIMIZE_MEMORY != 2
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_ENVIRONINDEX, 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])
#define LUA_IO_GETFIELD(f) lua_rawgeti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
/* "Pseudo-random" keys for the registry */
static
const
int
liolib_keys
[]
=
{(
int
)
&
luaL_callmeta
,
(
int
)
&
luaL_typerror
,
(
int
)
&
luaL_argerror
};
#endif
static
const
size_t
liolib_keys
[]
=
{(
size_t
)
&
luaL_callmeta
,
(
size_t
)
&
luaL_typerror
,
(
size_t
)
&
luaL_argerror
};
static
const
char
*
const
fnames
[]
=
{
"input"
,
"output"
};
static
int
pushresult
(
lua_State
*
L
,
int
i
,
const
char
*
filename
)
{
int
en
=
vfs_f
errno
(
0
)
;
/* calls to Lua API may change this value */
int
en
=
errno
;
/* calls to Lua API may change this value */
if
(
i
)
{
lua_pushboolean
(
L
,
1
);
return
1
;
...
...
@@ -47,9 +42,9 @@ static int pushresult (lua_State *L, int i, const char *filename) {
else
{
lua_pushnil
(
L
);
if
(
filename
)
lua_pushfstring
(
L
,
"%s:
err(%d)
"
,
filename
,
en
);
lua_pushfstring
(
L
,
"%s:
%s
"
,
filename
,
strerror
(
en
)
)
;
else
lua_pushfstring
(
L
,
"
err(%d)"
,
en
);
lua_pushfstring
(
L
,
"
%s"
,
strerror
(
en
)
)
;
lua_pushinteger
(
L
,
en
);
return
3
;
}
...
...
@@ -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
)
{
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
));
}
#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
)
{
...
...
@@ -72,7 +67,7 @@ static int io_type (lua_State *L) {
lua_getfield
(
L
,
LUA_REGISTRYINDEX
,
LUA_FILEHANDLE
);
if
(
ud
==
NULL
||
!
lua_getmetatable
(
L
,
1
)
||
!
lua_rawequal
(
L
,
-
2
,
-
1
))
lua_pushnil
(
L
);
/* not a file */
else
if
(
*
((
int
*
)
ud
)
<
FS_OPEN_OK
)
else
if
(
*
((
FILE
**
)
ud
)
==
NULL
)
lua_pushliteral
(
L
,
"closed file"
);
else
lua_pushliteral
(
L
,
"file"
);
...
...
@@ -80,9 +75,9 @@ static int io_type (lua_State *L) {
}
static
int
tofile
(
lua_State
*
L
)
{
int
*
f
=
tofilep
(
L
);
if
(
*
f
<
FS_OPEN_OK
)
static
FILE
*
tofile
(
lua_State
*
L
)
{
FILE
*
*
f
=
tofilep
(
L
);
if
(
*
f
==
NULL
)
luaL_error
(
L
,
"attempt to use a closed file"
);
return
*
f
;
}
...
...
@@ -94,91 +89,52 @@ static int tofile (lua_State *L) {
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
static
int
*
newfile
(
lua_State
*
L
)
{
int
*
pf
=
(
int
*
)
lua_newuserdata
(
L
,
sizeof
(
int
));
*
pf
=
FS_OPEN_OK
-
1
;
/* file handle is currently `closed' */
static
FILE
*
*
newfile
(
lua_State
*
L
)
{
FILE
*
*
pf
=
(
FILE
*
*
)
lua_newuserdata
(
L
,
sizeof
(
FILE
*
));
*
pf
=
NULL
;
/* file handle is currently `closed' */
luaL_getmetatable
(
L
,
LUA_FILEHANDLE
);
lua_setmetatable
(
L
,
-
2
);
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
)
{
#if LUA_OPTIMIZE_MEMORY != 2
lua_getfenv
(
L
,
1
);
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
)
FILE
**
p
=
tofilep
(
L
);
if
(
*
p
==
stdin
||
*
p
==
stdout
||
*
p
==
stderr
)
{
lua_pushnil
(
L
);
lua_pushliteral
(
L
,
"cannot close standard file"
);
return
2
;
}
int
ok
=
(
vfs_
close
(
*
p
)
==
0
);
*
p
=
FS_OPEN_OK
-
1
;
int
ok
=
(
f
close
(
*
p
)
==
0
);
*
p
=
NULL
;
return
pushresult
(
L
,
ok
,
NULL
);
#endif
}
static
int
io_close
(
lua_State
*
L
)
{
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 */
return
aux_close
(
L
);
}
static
int
io_gc
(
lua_State
*
L
)
{
int
f
=
*
tofilep
(
L
);
FILE
*
f
=
*
tofilep
(
L
);
/* ignore closed files */
if
(
f
!=
FS_OPEN_OK
-
1
)
if
(
f
!=
NULL
)
aux_close
(
L
);
return
0
;
}
static
int
io_tostring
(
lua_State
*
L
)
{
int
f
=
*
tofilep
(
L
);
if
(
f
==
FS_OPEN_OK
-
1
)
FILE
*
f
=
*
tofilep
(
L
);
if
(
f
==
NULL
)
lua_pushliteral
(
L
,
"file (closed)"
);
else
lua_pushfstring
(
L
,
"file (%
i
)"
,
f
);
lua_pushfstring
(
L
,
"file (%
p
)"
,
f
);
return
1
;
}
...
...
@@ -186,42 +142,19 @@ static int io_tostring (lua_State *L) {
static
int
io_open
(
lua_State
*
L
)
{
const
char
*
filename
=
luaL_checkstring
(
L
,
1
);
const
char
*
mode
=
luaL_optstring
(
L
,
2
,
"r"
);
int
*
pf
=
newfile
(
L
);
*
pf
=
vfs_open
(
filename
,
mode
);
return
(
*
pf
==
FS_OPEN_OK
-
1
)
?
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;
FILE
**
pf
=
newfile
(
L
);
*
pf
=
fopen
(
filename
,
mode
);
return
(
*
pf
==
NULL
)
?
pushresult
(
L
,
0
,
filename
)
:
1
;
}
static int io_tmpfile (lua_State *L) {
int *pf = newfile(L);
*pf = tmpfile();
return (*pf == FS_OPEN_OK - 1) ? pushresult(L, 0, NULL) : 1;
}
#endif
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
;
static
FILE
*
getiofile
(
lua_State
*
L
,
int
findex
)
{
FILE
*
f
;
lua_rawgeti
(
L
,
LUA_ENVIRONINDEX
,
findex
);
f
=
*
(
FILE
**
)
lua_touserdata
(
L
,
-
1
);
if
(
f
==
NULL
)
luaL_error
(
L
,
"standard %s file is closed"
,
fnames
[
findex
-
1
]);
return
f
;
}
...
...
@@ -229,19 +162,19 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
if
(
!
lua_isnoneornil
(
L
,
1
))
{
const
char
*
filename
=
lua_tostring
(
L
,
1
);
if
(
filename
)
{
int
*
pf
=
newfile
(
L
);
*
pf
=
vfs_
open
(
filename
,
mode
);
if
(
*
pf
==
FS_OPEN_OK
-
1
)
FILE
*
*
pf
=
newfile
(
L
);
*
pf
=
f
open
(
filename
,
mode
);
if
(
*
pf
==
NULL
)
fileerror
(
L
,
1
,
filename
);
}
else
{
tofile
(
L
);
/* check that it's a valid file handle */
lua_pushvalue
(
L
,
1
);
}
LUA_IO_SETFIELD
(
f
);
lua_rawseti
(
L
,
LUA_ENVIRONINDEX
,
f
);
}
/* return current value */
LUA_IO_GETFIELD
(
f
);
lua_rawgeti
(
L
,
LUA_ENVIRONINDEX
,
f
);
return
1
;
}
...
...
@@ -276,14 +209,14 @@ static int f_lines (lua_State *L) {
static
int
io_lines
(
lua_State
*
L
)
{
if
(
lua_isnoneornil
(
L
,
1
))
{
/* no arguments? */
/* will iterate over default input */
LUA_IO_GETFIELD
(
IO_INPUT
);
lua_rawgeti
(
L
,
LUA_ENVIRONINDEX
,
IO_INPUT
);
return
f_lines
(
L
);
}
else
{
const
char
*
filename
=
luaL_checkstring
(
L
,
1
);
int
*
pf
=
newfile
(
L
);
*
pf
=
vfs_
open
(
filename
,
"r"
);
if
(
*
pf
==
FS_OPEN_OK
-
1
)
FILE
*
*
pf
=
newfile
(
L
);
*
pf
=
f
open
(
filename
,
"r"
);
if
(
*
pf
==
NULL
)
fileerror
(
L
,
1
,
filename
);
aux_lines
(
L
,
lua_gettop
(
L
),
1
);
return
1
;
...
...
@@ -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
;
if (fs
_s
canf(f, LUA_NUMBER_SCAN, &d) == 1) {
if
(
fscanf
(
f
,
LUA_NUMBER_SCAN
,
&
d
)
==
1
)
{
lua_pushnumber
(
L
,
d
);
return
1
;
}
...
...
@@ -309,27 +242,27 @@ static int read_number (lua_State *L, int f) {
return
0
;
/* read fails */
}
}
#endif
static
int
test_eof
(
lua_State
*
L
,
int
f
)
{
int
c
=
vfs_getc
(
f
);
vfs_ungetc
(
c
,
f
);
static
int
test_eof
(
lua_State
*
L
,
FILE
*
f
)
{
int
c
=
getc
(
f
);
ungetc
(
c
,
f
);
lua_pushlstring
(
L
,
NULL
,
0
);
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_buffinit
(
L
,
&
b
);
for
(;;)
{
size_t
l
;
char
*
p
=
luaL_prepbuffer
(
&
b
);
if (f
s_
gets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
if
(
fgets
(
p
,
LUAL_BUFFERSIZE
,
f
)
==
NULL
)
{
/* eof? */
luaL_pushresult
(
&
b
);
/* close buffer */
return
(
lua_objlen
(
L
,
-
1
)
>
0
);
/* check whether read something */
}
l =
c_
strlen(p);
l
=
strlen
(
p
);
if
(
l
==
0
||
p
[
l
-
1
]
!=
'\n'
)
luaL_addsize
(
&
b
,
l
);
else
{
...
...
@@ -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
nr
;
/* number of chars actually read */
luaL_Buffer
b
;
...
...
@@ -368,7 +283,7 @@ static int read_chars (lua_State *L, int f, size_t n) {
do
{
char
*
p
=
luaL_prepbuffer
(
&
b
);
if
(
rlen
>
n
)
rlen
=
n
;
/* cannot read more than asked */
nr
=
vfs_
read
(
f
,
p
,
rlen
);
nr
=
f
read
(
p
,
sizeof
(
char
)
,
rlen
,
f
);
luaL_addsize
(
&
b
,
nr
);
n
-=
nr
;
/* still have to read `n' chars */
}
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) {
}
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
success
;
int
n
;
//vfs_
clearerr(f);
clearerr
(
f
);
if
(
nargs
==
0
)
{
/* no arguments? */
success
=
read_line
(
L
,
f
);
n
=
first
+
1
;
/* to return 1 result */
...
...
@@ -398,11 +313,9 @@ static int g_read (lua_State *L, int f, int first) {
const
char
*
p
=
lua_tostring
(
L
,
n
);
luaL_argcheck
(
L
,
p
&&
p
[
0
]
==
'*'
,
n
,
"invalid option"
);
switch
(
p
[
1
])
{
#if 0
case
'n'
:
/* number */
success
=
read_number
(
L
,
f
);
break
;
#endif
case
'l'
:
/* line */
success
=
read_line
(
L
,
f
);
break
;
...
...
@@ -416,7 +329,7 @@ static int g_read (lua_State *L, int f, int first) {
}
}
}
if
(
vfs_
ferr
n
o
(
f
))
if
(
ferro
r
(
f
))
return
pushresult
(
L
,
0
,
NULL
);
if
(
!
success
)
{
lua_pop
(
L
,
1
);
/* remove last result */
...
...
@@ -437,15 +350,13 @@ static int f_read (lua_State *L) {
static
int
io_readline
(
lua_State
*
L
)
{
int
*
p
f
=
(
int
*
)
lua_touserdata
(
L
,
lua_upvalueindex
(
1
));
FILE
*
f
=
*
(
FILE
*
*
)
lua_touserdata
(
L
,
lua_upvalueindex
(
1
));
int
sucess
;
if
(
p
f
==
NULL
||
*
pf
==
FS_OPEN_OK
-
1
){
/* file is already closed? */
if
(
f
==
NULL
)
/* file is already closed? */
luaL_error
(
L
,
"file is already closed"
);
return
0
;
}
sucess
=
read_line
(
L
,
*
pf
);
if
(
vfs_ferrno
(
*
pf
))
return
luaL_error
(
L
,
"err(%d)"
,
vfs_ferrno
(
*
pf
));
sucess
=
read_line
(
L
,
f
);
if
(
ferror
(
f
))
return
luaL_error
(
L
,
"%s"
,
strerror
(
errno
));
if
(
sucess
)
return
1
;
else
{
/* EOF */
if
(
lua_toboolean
(
L
,
lua_upvalueindex
(
2
)))
{
/* generator created file? */
...
...
@@ -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
status
=
1
;
for
(;
nargs
--
;
arg
++
)
{
#if 0
if
(
lua_type
(
L
,
arg
)
==
LUA_TNUMBER
)
{
/* optimization: could be done exactly as for strings */
status
=
status
&&
f
s_
printf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
fprintf
(
f
,
LUA_NUMBER_FMT
,
lua_tonumber
(
L
,
arg
))
>
0
;
}
else
#endif
{
else
{
size_t
l
;
const
char
*
s
=
luaL_checklstring
(
L
,
arg
,
&
l
);
status
=
status
&&
(
vfs_
write
(
f
,
s
,
l
)
==
l
);
status
=
status
&&
(
f
write
(
s
,
s
izeof
(
char
),
l
,
f
)
==
l
);
}
}
return
pushresult
(
L
,
status
,
NULL
);
...
...
@@ -493,75 +401,68 @@ static int f_write (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
};
int
f
=
tofile
(
L
);
FILE
*
f
=
tofile
(
L
);
int
op
=
luaL_checkoption
(
L
,
2
,
"cur"
,
modenames
);
long
offset
=
luaL_optlong
(
L
,
3
,
0
);
op
=
vfs_l
seek
(
f
,
offset
,
mode
[
op
]);
op
=
f
seek
(
f
,
offset
,
mode
[
op
]);
if
(
op
)
return
pushresult
(
L
,
0
,
NULL
);
/* error */
else
{
lua_pushinteger
(
L
,
vfs_
tell
(
f
));
lua_pushinteger
(
L
,
f
tell
(
f
));
return
1
;
}
}
#if 0
static
int
f_setvbuf
(
lua_State
*
L
)
{
static
const
int
mode
[]
=
{
_IONBF
,
_IOFBF
,
_IOLBF
};
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
);
lua_Integer
sz
=
luaL_optinteger
(
L
,
3
,
LUAL_BUFFERSIZE
);
int
res
=
setvbuf
(
f
,
NULL
,
mode
[
op
],
sz
);
return
pushresult
(
L
,
res
==
0
,
NULL
);
}
#endif
static
int
io_flush
(
lua_State
*
L
)
{
return
pushresult
(
L
,
vfs_
flush
(
getiofile
(
L
,
IO_OUTPUT
))
==
0
,
NULL
);
return
pushresult
(
L
,
f
flush
(
getiofile
(
L
,
IO_OUTPUT
))
==
0
,
NULL
);
}
static
int
f_flush
(
lua_State
*
L
)
{
return
pushresult
(
L
,
vfs_
flush
(
tofile
(
L
))
==
0
,
NULL
);
return
pushresult
(
L
,
f
flush
(
tofile
(
L
))
==
0
,
NULL
);
}
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
#if LUA_OPTIMIZE_MEMORY == 2
const
LUA_REG_TYPE
iolib_funcs
[]
=
{
#else
const
LUA_REG_TYPE
iolib
[]
=
{
#endif
{
LSTRKEY
(
"close"
),
LFUNCVAL
(
io_close
)},
{
LSTRKEY
(
"flush"
),
LFUNCVAL
(
io_flush
)},
{
LSTRKEY
(
"input"
),
LFUNCVAL
(
io_input
)},
{
LSTRKEY
(
"lines"
),
LFUNCVAL
(
io_lines
)},
{
LSTRKEY
(
"open"
),
LFUNCVAL
(
io_open
)},
{
LSTRKEY
(
"output"
),
LFUNCVAL
(
io_output
)},
// {LSTRKEY("popen"), LFUNCVAL(io_popen)},
{
LSTRKEY
(
"read"
),
LFUNCVAL
(
io_read
)},
// {LSTRKEY("tmpfile"), LFUNCVAL(io_tmpfile)},
{
LSTRKEY
(
"type"
),
LFUNCVAL
(
io_type
)},
{
LSTRKEY
(
"write"
),
LFUNCVAL
(
io_write
)},
{
LSTRKEY
(
"__index"
),
LROVAL
(
iolib_funcs
)},
{
LNILKEY
,
LNILVAL
}
};
#if LUA_OPTIMIZE_MEMORY == 2
static
int
luaL_index
(
lua_State
*
L
)
/* Note that IO objects use a RAM metatable created to allow extensibility */
static
int
io_index
(
lua_State
*
L
)
{
return
luaR_findfunction
(
L
,
iolib_funcs
);
}
const
luaL_Reg
iolib
[]
=
{
{
"__index"
,
luaL
_index
},
{
"__index"
,
io
_index
},
{
NULL
,
NULL
}
};
#endif
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
...
...
@@ -572,80 +473,31 @@ const LUA_REG_TYPE flib[] = {
{
LSTRKEY
(
"lines"
),
LFUNCVAL
(
f_lines
)},
{
LSTRKEY
(
"read"
),
LFUNCVAL
(
f_read
)},
{
LSTRKEY
(
"seek"
),
LFUNCVAL
(
f_seek
)},
//
{LSTRKEY("setvbuf"), LFUNCVAL(f_setvbuf)},
{
LSTRKEY
(
"setvbuf"
),
LFUNCVAL
(
f_setvbuf
)},
{
LSTRKEY
(
"write"
),
LFUNCVAL
(
f_write
)},
{
LSTRKEY
(
"__gc"
),
LFUNCVAL
(
io_gc
)},
{
LSTRKEY
(
"__tostring"
),
LFUNCVAL
(
io_tostring
)},
#if LUA_OPTIMIZE_MEMORY > 0
{
LSTRKEY
(
"__index"
),
LROVAL
(
flib
)},
#endif
{
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
;
#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_rawseti
(
L
,
LUA_REGISTRYINDEX
,
liolib_keys
[
k
]);
lua_rawseti
(
L
,
LUA_REGISTRYINDEX
,
(
int
)(
liolib_keys
[
k
])
)
;
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
)
{
createmeta
(
L
);
#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_rometatable
(
L
,
LUA_FILEHANDLE
,
(
void
*
)
flib
);
/* create metatable for file handles */
luaL_register_light
(
L
,
LUA_IOLIBNAME
,
iolib
);
lua_pushvalue
(
L
,
-
1
);
lua_setmetatable
(
L
,
-
2
);
#endif
#if 0
/* create (and set) default files */
createstdfile(L, c_stdin, IO_INPUT, "stdin");
createstdfile(L, c_stdout, IO_OUTPUT, "stdout");
createstdfile(L, c_stderr, IO_STDERR, "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
createstdfile
(
L
,
stdin
,
IO_INPUT
,
"stdin"
);
createstdfile
(
L
,
stdout
,
IO_OUTPUT
,
"stdout"
);
createstdfile
(
L
,
stderr
,
0
,
"stderr"
);
return
1
;
}
app/lua/luac_cross/luac.c
View file @
27a83feb
...
...
@@ -11,13 +11,14 @@
#include C_HEADER_STDIO
#include C_HEADER_STDLIB
#include C_HEADER_STRING
#include <time.h>
#define luac_c
#define LUA_CORE
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
...
...
@@ -32,16 +33,22 @@
static
int
listing
=
0
;
/* list bytecodes? */
static
int
dumping
=
1
;
/* dump bytecodes? */
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
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
DumpTargetInfo
target
;
static
void
fatal
(
const
char
*
message
)
void
luac_
fatal
(
const
char
*
message
)
{
fprintf
(
stderr
,
"%s: %s
\n
"
,
progname
,
message
);
exit
(
EXIT_FAILURE
);
}
#define fatal(s) luac_fatal(s)
static
void
cannot
(
const
char
*
what
)
{
...
...
@@ -61,18 +68,21 @@ static void usage(const char* message)
" - process stdin
\n
"
" -l list
\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
"
" -s strip debug 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
"
,
progname
,
Output
);
exit
(
EXIT_FAILURE
);
}
#define IS(s) (strcmp(argv[i],s)==0)
#define IROM0_SEG 0x40210000ul
#define IROM0_SEGMAX 0x00100000ul
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 */
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 */
++
listing
;
else
if
(
IS
(
"-o"
))
/* output file */
...
...
@@ -99,42 +129,17 @@ static int doargs(int argc, char* argv[])
if
(
output
==
NULL
||
*
output
==
0
)
usage
(
LUA_QL
(
"-o"
)
" needs argument"
);
if
(
IS
(
"-"
))
output
=
NULL
;
}
else
if
(
IS
(
"-p"
))
/* parse only */
dumping
=
0
;
else
if
(
IS
(
"-s"
))
/* strip debug information */
stripping
=
1
;
else
if
(
IS
(
"-v"
))
/* show 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 */
usage
(
argv
[
i
]);
}
if
(
i
==
argc
&&
(
listing
||
!
dumping
))
{
dumping
=
0
;
...
...
@@ -150,30 +155,99 @@ static int doargs(int argc, char* argv[])
#define toproto(L,i) (clvalue(L->top+(i))->l.p)
static
const
Proto
*
combin
e
(
lua_State
*
L
,
int
n
)
static
TString
*
corenam
e
(
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
);
else
{
int
i
,
pc
;
int
i
;
Instruction
*
pc
;
Proto
*
f
=
luaF_newproto
(
L
);
setptvalue2s
(
L
,
L
->
top
,
f
);
incr_top
(
L
);
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
->
sizep
=
n
;
pc
=
0
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
f
->
p
[
i
]
=
toproto
(
L
,
i
-
n
-
1
);
f
->
code
[
pc
++
]
=
CREATE_ABx
(
OP_CLOSURE
,
0
,
i
);
f
->
code
[
pc
++
]
=
CREATE_ABC
(
OP_CALL
,
0
,
1
,
1
);
pc
=
0
;
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
;
}
}
...
...
@@ -189,6 +263,9 @@ struct Smain {
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
)
{
struct
Smain
*
s
=
(
struct
Smain
*
)
lua_touserdata
(
L
,
1
);
...
...
@@ -197,19 +274,39 @@ static int pmain(lua_State* L)
const
Proto
*
f
;
int
i
;
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
++
)
{
const
char
*
filename
=
IS
(
"-"
)
?
NULL
:
argv
[
i
];
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
(
dumping
)
{
int
result
;
FILE
*
D
=
(
output
==
NULL
)
?
stdout
:
fopen
(
output
,
"wb"
);
if
(
D
==
NULL
)
cannot
(
"open"
);
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
);
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"
);
...
...
@@ -234,7 +331,7 @@ int main(int argc, char* argv[])
int
i
=
doargs
(
argc
,
argv
);
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
();
if
(
L
==
NULL
)
fatal
(
"not enough memory for state"
);
s
.
argc
=
argc
;
...
...
app/lua/luaconf.h
View file @
27a83feb
...
...
@@ -38,6 +38,11 @@
#define LUA_WIN
#endif
#if defined(LUA_CROSS_COMPILER)
#define LUA_USE_LINUX
#endif
#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN
/* needs an extra library: -ldl */
...
...
@@ -59,7 +64,7 @@
#if defined(LUA_USE_POSIX)
#define LUA_USE_MKSTEMP
#define LUA_USE_ISATTY
#define LUA_USE_POPEN
//
#define LUA_USE_POPEN
#define LUA_USE_ULONGJMP
#endif
...
...
@@ -167,7 +172,7 @@
#define LUA_INTEGER ptrdiff_t
#else
#if !defined LUA_INTEGRAL_LONGLONG
#define LUA_INTEGER
long
#define LUA_INTEGER
int
#else
#define LUA_INTEGER long long
#endif // #if !defined LUA_INTEGRAL_LONGLONG
...
...
@@ -487,7 +492,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
/* 16-bit ints */
#define LUAI_UINT32 unsigned long
#define LUAI_INT32 long
#define LUAI_MAXINT32
LONG
_MAX
#define LUAI_MAXINT32
INT
_MAX
#define LUAI_UMEM unsigned long
#define LUAI_MEM long
#endif
...
...
@@ -607,8 +612,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
*/
#if defined LUA_NUMBER_INTEGRAL
#if !defined LUA_INTEGRAL_LONGLONG
#define LUA_NUMBER_SCAN "%
l
d"
#define LUA_NUMBER_FMT "%
l
d"
#define LUA_NUMBER_SCAN "%d"
#define LUA_NUMBER_FMT "%d"
#else
#define LUA_NUMBER_SCAN "%lld"
#define LUA_NUMBER_FMT "%lld"
...
...
@@ -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
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
#endif
...
...
app/lua/lundump.c
View file @
27a83feb
...
...
@@ -172,7 +172,7 @@ static TString* LoadString(LoadState* S)
}
else
{
s
=
(
char
*
)
luaZ_get_crt_address
(
S
->
Z
);
LoadBlock
(
S
,
NULL
,
size
);
return
luaS_new
ro
lstr
(
S
->
L
,
s
,
size
-
1
);
return
luaS_newlstr
(
S
->
L
,
s
,
size
-
1
);
}
}
}
...
...
@@ -280,7 +280,7 @@ static Proto* LoadFunction(LoadState* S, TString* p)
Proto
*
f
;
if
(
++
S
->
L
->
nCcalls
>
LUAI_MAXCCALLS
)
error
(
S
,
"code too deep"
);
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
);
f
->
source
=
LoadString
(
S
);
if
(
f
->
source
==
NULL
)
f
->
source
=
p
;
f
->
linedefined
=
LoadInt
(
S
);
...
...
app/lua/lvm.c
View file @
27a83feb
Prev
1
2
3
4
5
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment