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
11592951
Unverified
Commit
11592951
authored
Dec 07, 2018
by
Arnim Läuger
Committed by
GitHub
Dec 07, 2018
Browse files
Merge pull request #2582 from nodemcu/dev
Next master drop
parents
4095c408
61433c44
Changes
125
Hide whitespace changes
Inline
Side-by-side
app/lua/lmathlib.c
View file @
11592951
...
...
@@ -15,7 +15,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#undef PI
#define PI (3.14159265358979323846)
...
...
app/lua/loadlib.c
View file @
11592951
...
...
@@ -24,7 +24,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
...
...
@@ -474,10 +473,11 @@ static int ll_require (lua_State *L) {
return
1
;
/* package is already loaded */
}
/* Is this a readonly table? */
void
*
res
=
luaR_findglobal
(
name
,
c_strlen
(
name
));
if
(
res
)
{
lua_pushrotable
(
L
,
res
);
lua_getfield
(
L
,
LUA_GLOBALSINDEX
,
name
);
if
(
lua_isrotable
(
L
,
-
1
))
{
return
1
;
}
else
{
lua_pop
(
L
,
1
);
}
/* else must load it; iterate over available loaders */
lua_getfield
(
L
,
LUA_ENVIRONINDEX
,
"loaders"
);
...
...
@@ -563,8 +563,13 @@ static void modinit (lua_State *L, const char *modname) {
static
int
ll_module
(
lua_State
*
L
)
{
const
char
*
modname
=
luaL_checkstring
(
L
,
1
);
if
(
luaR_findglobal
(
modname
,
c_strlen
(
modname
)))
/* Is this a readonly table? */
lua_getfield
(
L
,
LUA_GLOBALSINDEX
,
modname
);
if
(
lua_isrotable
(
L
,
-
1
))
{
return
0
;
}
else
{
lua_pop
(
L
,
1
);
}
int
loaded
=
lua_gettop
(
L
)
+
1
;
/* index of _LOADED table */
lua_getfield
(
L
,
LUA_REGISTRYINDEX
,
"_LOADED"
);
lua_getfield
(
L
,
loaded
,
modname
);
/* get _LOADED[modname] */
...
...
app/lua/lobject.h
View file @
11592951
...
...
@@ -34,20 +34,33 @@
#define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3)
#ifdef __XTENSA__
/*
** force aligned access to critical fields in Flash-based structures
** wo is the offset of aligned word in bytes 0,4,8,..
** bo is the field within the word in bits 0..31
*/
#define GET_BYTE_FN(name,t,wo,bo) \
static inline lu_byte get ## name(void *o) { \
lu_byte res;
/* extract named field */
\
asm ("l32i %0, %1, " #wo "; extui %0, %0, " #bo ", 8;" : "=r"(res) : "r"(o) : );\
return res; }
#else
#define GET_BYTE_FN(name,t,wo,bo) \
static inline lu_byte get ## name(void *o) { return ((t *)o)->name; }
#endif
/*
** Union of all collectable objects
*/
typedef
union
GCObject
GCObject
;
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/*
** Common header in struct form
*/
...
...
@@ -55,11 +68,18 @@ typedef struct GCheader {
CommonHeader
;
}
GCheader
;
/*
** Word aligned inline access functions for the CommonHeader tt and marked fields.
** Note that these MUST be consistent with the CommonHeader definition above. Arg
** 3 is a word offset (4 bytes in this case) and arg 4 the bit offset in the word.
*/
GET_BYTE_FN
(
tt
,
GCheader
,
4
,
0
)
GET_BYTE_FN
(
marked
,
GCheader
,
4
,
8
)
#if defined(LUA_PACK_VALUE) || defined(ELUA_ENDIAN_BIG) || defined(ELUA_ENDIAN_SMALL)
# error "NodeMCU does not support the eLua LUA_PACK_VALUE and ELUA_ENDIAN defines"
#endif
/*
** Union of all Lua values
*/
...
...
@@ -214,7 +234,6 @@ typedef struct lua_TValue {
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
typedef
TValue
*
StkId
;
/* index to stack elements */
...
...
@@ -386,6 +405,7 @@ typedef struct Table {
int
sizearray
;
/* size of `array' array */
}
Table
;
typedef
const
struct
luaR_entry
ROTable
;
/*
** `module' operation for hashing (size is always a power of 2)
...
...
app/lua/lrodefs.h
View file @
11592951
...
...
@@ -38,5 +38,10 @@
return 1
#endif
#define LROT_TABENTRY(n,t) {LSTRKEY(#n), LRO_ROVAL(t)}
#define LROT_FUNCENTRY(n,f) {LSTRKEY(#n), LRO_FUNCVAL(f)}
#define LROT_NUMENTRY(n,x) {LSTRKEY(#n), LRO_NUMVAL(x)}
#define LROT_END {LNILKEY, LNILVAL}
#endif
/* lrodefs_h */
app/lua/lrotable.c
View file @
11592951
...
...
@@ -9,77 +9,139 @@
#include "lobject.h"
#include "lapi.h"
/* Local defines */
#define LUAR_FINDFUNCTION 0
#define LUAR_FINDVALUE 1
/* Externally defined read-only table array */
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
)
{
unsigned
i
;
if
(
c_strlen
(
name
)
>
LUA_MAX_ROTABLE_NAME
)
return
NULL
;
for
(
i
=
0
;
lua_rotable
[
i
].
name
;
i
++
)
if
(
*
lua_rotable
[
i
].
name
!=
'\0'
&&
c_strlen
(
lua_rotable
[
i
].
name
)
==
len
&&
!
c_strncmp
(
lua_rotable
[
i
].
name
,
name
,
len
))
{
return
(
void
*
)(
lua_rotable
[
i
].
pentries
);
#define ALIGNED_STRING (__attribute__((aligned(4))) char *)
#define LA_LINES 16
#define LA_SLOTS 4
//#define COLLECT_STATS
/*
* All keyed ROtable access passes through luaR_findentry(). ROTables
* are simply a list of <key><TValue value> pairs. The existing algo
* did a linear scan of this vector of pairs looking for a match.
*
* A N×M lookaside cache has been added, with a simple hash on the key's
* TString addr and the ROTable addr to identify one of N lines. Each
* line has M slots which are scanned. This is all done in RAM and is
* perhaps 20x faster than the corresponding random Flash accesses which
* will cause flash faults.
*
* If a match is found and the table addresses match, then this entry is
* probed first. In practice the hit-rate here is over 99% so the code
* rarely fails back to doing the linear scan in ROM.
*
* Note that this hash does a couple of prime multiples and a modulus 2^X
* with is all evaluated in H/W, and adequately randomizes the lookup.
*/
#define HASH(a,b) (519*((size_t)(a)>>4) + 17*((size_t)(b)>>4))
static
struct
{
unsigned
hash
;
unsigned
addr
:
24
;
unsigned
ndx
:
8
;
}
cache
[
LA_LINES
][
LA_SLOTS
];
#ifdef COLLECT_STATS
unsigned
cache_stats
[
3
];
#define COUNT(i) cache_stats[i]++
#else
#define COUNT(i)
#endif
static
int
lookup_cache
(
unsigned
hash
,
ROTable
*
rotable
)
{
int
i
=
(
hash
>>
2
)
&
(
LA_LINES
-
1
),
j
;
for
(
j
=
0
;
j
<
LA_SLOTS
;
j
++
)
{
if
(
cache
[
i
][
j
].
hash
==
hash
&&
((
size_t
)
rotable
&
0xffffffu
)
==
cache
[
i
][
j
].
addr
)
{
COUNT
(
0
);
return
cache
[
i
][
j
].
ndx
;
}
return
NULL
;
}
COUNT
(
1
);
return
-
1
;
}
/* Find an entry in a rotable and return it */
static
const
TValue
*
luaR_auxfind
(
const
luaR_entry
*
pentry
,
const
char
*
strkey
,
luaR_numkey
numkey
,
unsigned
*
ppos
)
{
const
TValue
*
res
=
NULL
;
unsigned
i
=
0
;
if
(
pentry
==
NULL
)
return
NULL
;
while
(
pentry
->
key
.
type
!=
LUA_TNIL
)
{
if
((
strkey
&&
(
pentry
->
key
.
type
==
LUA_TSTRING
)
&&
(
!
c_strcmp
(
pentry
->
key
.
id
.
strkey
,
strkey
)))
||
(
!
strkey
&&
(
pentry
->
key
.
type
==
LUA_TNUMBER
)
&&
((
luaR_numkey
)
pentry
->
key
.
id
.
numkey
==
numkey
)))
{
res
=
&
pentry
->
value
;
break
;
static
void
update_cache
(
unsigned
hash
,
ROTable
*
rotable
,
unsigned
ndx
)
{
int
i
=
(
hash
)
>>
2
&
(
LA_LINES
-
1
),
j
;
COUNT
(
2
);
if
(
ndx
>
0xffu
)
return
;
for
(
j
=
LA_SLOTS
-
1
;
j
>
0
;
j
--
)
cache
[
i
][
j
]
=
cache
[
i
][
j
-
1
];
cache
[
i
][
0
].
hash
=
hash
;
cache
[
i
][
0
].
addr
=
(
size_t
)
rotable
;
cache
[
i
][
0
].
ndx
=
ndx
;
}
/*
* Find a string key entry in a rotable and return it. Note that this internally
* uses a null key to denote a metatable search.
*/
const
TValue
*
luaR_findentry
(
ROTable
*
rotable
,
TString
*
key
,
unsigned
*
ppos
)
{
const
luaR_entry
*
pentry
=
rotable
;
const
char
*
strkey
=
key
?
getstr
(
key
)
:
ALIGNED_STRING
"__metatable"
;
size_t
hash
=
HASH
(
rotable
,
key
);
unsigned
i
=
0
;
int
j
=
lookup_cache
(
hash
,
rotable
);
if
(
pentry
)
{
if
(
j
>=
0
){
if
((
pentry
[
j
].
key
.
type
==
LUA_TSTRING
)
&&
!
c_strcmp
(
pentry
[
j
].
key
.
id
.
strkey
,
strkey
))
{
if
(
ppos
)
*
ppos
=
j
;
return
&
pentry
[
j
].
value
;
}
}
/*
* The invariants for 1st word comparison are deferred to here since they
* aren't needed if there is a cache hit. Note that the termination null
* is included so a "on\0" has a mask of 0xFFFFFF and "a\0" has 0xFFFF.
*/
unsigned
name4
=
*
(
unsigned
*
)
strkey
;
unsigned
l
=
key
?
key
->
tsv
.
len
:
sizeof
(
"__metatable"
)
-
1
;
unsigned
mask4
=
l
>
2
?
(
~
0u
)
:
(
~
0u
)
>>
((
3
-
l
)
*
8
);
for
(;
pentry
->
key
.
type
!=
LUA_TNIL
;
i
++
,
pentry
++
)
{
if
((
pentry
->
key
.
type
==
LUA_TSTRING
)
&&
((
*
(
unsigned
*
)
pentry
->
key
.
id
.
strkey
^
name4
)
&
mask4
)
==
0
&&
!
c_strcmp
(
pentry
->
key
.
id
.
strkey
,
strkey
))
{
if
(
ppos
)
*
ppos
=
i
;
if
(
j
==-
1
)
{
update_cache
(
hash
,
rotable
,
pentry
-
rotable
);
}
else
if
(
j
!=
(
pentry
-
rotable
))
{
j
=
0
;
}
return
&
pentry
->
value
;
}
}
i
++
;
pentry
++
;
}
if
(
res
&&
ppos
)
*
ppos
=
i
;
return
res
;
return
luaO_nilobject
;
}
int
luaR_findfunction
(
lua_State
*
L
,
const
luaR_entry
*
ptable
)
{
const
TValue
*
res
=
NULL
;
const
char
*
key
=
luaL_checkstring
(
L
,
2
);
res
=
luaR_auxfind
(
ptable
,
key
,
0
,
NULL
);
if
(
res
&&
ttislightfunction
(
res
))
{
luaA_pushobject
(
L
,
res
);
return
1
;
const
TValue
*
luaR_findentryN
(
ROTable
*
rotable
,
luaR_numkey
numkey
,
unsigned
*
ppos
)
{
unsigned
i
=
0
;
const
luaR_entry
*
pentry
=
rotable
;
if
(
pentry
)
{
for
(
;
pentry
->
key
.
type
!=
LUA_TNIL
;
i
++
,
pentry
++
)
{
if
(
pentry
->
key
.
type
==
LUA_TNUMBER
&&
(
luaR_numkey
)
pentry
->
key
.
id
.
numkey
==
numkey
)
{
if
(
ppos
)
*
ppos
=
i
;
return
&
pentry
->
value
;
}
}
}
else
return
0
;
return
NULL
;
}
/* Find an entry in a rotable and return its type
If "strkey" is not NULL, the function will look for a string key,
otherwise it will look for a number key */
const
TValue
*
luaR_findentry
(
void
*
data
,
const
char
*
strkey
,
luaR_numkey
numkey
,
unsigned
*
ppos
)
{
return
luaR_auxfind
((
const
luaR_entry
*
)
data
,
strkey
,
numkey
,
ppos
);
}
/* Find the metatable of a given table */
void
*
luaR_getmeta
(
void
*
data
)
{
#ifdef LUA_META_ROTABLES
const
TValue
*
res
=
luaR_auxfind
((
const
luaR_entry
*
)
data
,
"__metatable"
,
0
,
NULL
);
void
*
luaR_getmeta
(
ROTable
*
rotable
)
{
const
TValue
*
res
=
luaR_findentry
(
rotable
,
NULL
,
NULL
);
return
res
&&
ttisrotable
(
res
)
?
rvalue
(
res
)
:
NULL
;
#else
return
NULL
;
#endif
}
static
void
luaR_next_helper
(
lua_State
*
L
,
const
luaR_entry
*
pentries
,
int
pos
,
TValue
*
key
,
TValue
*
val
)
{
static
void
luaR_next_helper
(
lua_State
*
L
,
ROTable
*
pentries
,
int
pos
,
TValue
*
key
,
TValue
*
val
)
{
setnilvalue
(
key
);
setnilvalue
(
val
);
if
(
pentries
[
pos
].
key
.
type
!=
LUA_TNIL
)
{
...
...
@@ -91,56 +153,24 @@ static void luaR_next_helper(lua_State *L, const luaR_entry *pentries, int pos,
setobj2s
(
L
,
val
,
&
pentries
[
pos
].
value
);
}
}
/* next (used for iteration) */
void
luaR_next
(
lua_State
*
L
,
void
*
data
,
TValue
*
key
,
TValue
*
val
)
{
const
luaR_entry
*
pentries
=
(
const
luaR_entry
*
)
data
;
char
strkey
[
LUA_MAX_ROTABLE_NAME
+
1
],
*
pstrkey
=
NULL
;
luaR_numkey
numkey
=
0
;
void
luaR_next
(
lua_State
*
L
,
ROTable
*
rotable
,
TValue
*
key
,
TValue
*
val
)
{
unsigned
keypos
;
/* Special case: if key is nil, return the first element of the rotable */
if
(
ttisnil
(
key
))
luaR_next_helper
(
L
,
pentries
,
0
,
key
,
val
);
if
(
ttisnil
(
key
))
luaR_next_helper
(
L
,
rotable
,
0
,
key
,
val
);
else
if
(
ttisstring
(
key
)
||
ttisnumber
(
key
))
{
/* Find the previou
d
key again */
/* Find the previou
s
key again */
if
(
ttisstring
(
key
))
{
luaR_getcstr
(
strkey
,
rawtsvalue
(
key
),
LUA_MAX_ROTABLE_NAME
);
pstrkey
=
strkey
;
}
else
numkey
=
(
luaR_numkey
)
nvalue
(
key
);
luaR_findentry
(
data
,
pstrkey
,
numkey
,
&
keypos
);
luaR_findentry
(
rotable
,
rawtsvalue
(
key
),
&
keypos
);
}
else
{
luaR_findentryN
(
rotable
,
(
luaR_numkey
)
nvalue
(
key
),
&
keypos
);
}
/* Advance to next key */
keypos
++
;
luaR_next_helper
(
L
,
pentries
,
keypos
,
key
,
val
);
keypos
++
;
luaR_next_helper
(
L
,
rotable
,
keypos
,
key
,
val
);
}
}
/* Convert a Lua string to a C string */
void
luaR_getcstr
(
char
*
dest
,
const
TString
*
src
,
size_t
maxsize
)
{
if
(
src
->
tsv
.
len
+
1
>
maxsize
)
dest
[
0
]
=
'\0'
;
else
{
c_memcpy
(
dest
,
getstr
(
src
),
src
->
tsv
.
len
);
dest
[
src
->
tsv
.
len
]
=
'\0'
;
}
}
#ifdef LUA_META_ROTABLES
/* Set in RO check depending on platform */
#if defined(LUA_CROSS_COMPILER) && defined(__CYGWIN__)
extern
char
__end__
[];
#define IN_RO_AREA(p) ((p) < __end__)
#elif defined(LUA_CROSS_COMPILER)
extern
char
_edata
[];
#define IN_RO_AREA(p) ((p) < _edata)
#else
/* xtensa tool chain for ESP target */
extern
char
_irom0_text_start
[];
extern
char
_irom0_text_end
[];
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
#endif
/* Return 1 if the given pointer is a rotable */
int
luaR_isrotable
(
void
*
p
)
{
return
IN_RO_AREA
((
char
*
)
p
);
}
#endif
app/lua/lrotable.h
View file @
11592951
...
...
@@ -14,7 +14,11 @@
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#ifdef LUA_CROSS_COMPILER
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = k}}
#else
#define LRO_STRKEY(k) {LUA_TSTRING, {.strkey = (STORE_ATTR char *) k}}
#endif
#define LRO_NUMKEY(k) {LUA_TNUMBER, {.numkey = k}}
#define LRO_NILKEY {LUA_TNIL, {.strkey=NULL}}
...
...
@@ -25,40 +29,58 @@
typedef
int
luaR_numkey
;
/* The next structure defines the type of a key */
typedef
struct
{
typedef
struct
{
int
type
;
union
{
union
{
const
char
*
strkey
;
luaR_numkey
numkey
;
}
id
;
}
luaR_key
;
/* An entry in the read only table */
typedef
struct
{
typedef
struct
luaR_entry
{
const
luaR_key
key
;
const
TValue
value
;
}
luaR_entry
;
/* A rotable */
typedef
struct
{
const
char
*
name
;
const
luaR_entry
*
pentries
;
}
luaR_table
;
void
*
luaR_findglobal
(
const
char
*
key
,
unsigned
len
);
int
luaR_findfunction
(
lua_State
*
L
,
const
luaR_entry
*
ptable
);
const
TValue
*
luaR_findentry
(
void
*
data
,
const
char
*
strkey
,
luaR_numkey
numkey
,
unsigned
*
ppos
);
void
luaR_getcstr
(
char
*
dest
,
const
TString
*
src
,
size_t
maxsize
);
void
luaR_next
(
lua_State
*
L
,
void
*
data
,
TValue
*
key
,
TValue
*
val
);
void
*
luaR_getmeta
(
void
*
data
);
#ifdef LUA_META_ROTABLES
/*
* The current ROTable implmentation is a vector of luaR_entry terminated by a
* nil record. The convention is to use ROtable * to refer to the entire vector
* as a logical ROTable.
*/
typedef
const
struct
luaR_entry
ROTable
;
const
TValue
*
luaR_findentry
(
ROTable
*
tab
,
TString
*
key
,
unsigned
*
ppos
);
const
TValue
*
luaR_findentryN
(
ROTable
*
tab
,
luaR_numkey
numkey
,
unsigned
*
ppos
);
void
luaR_next
(
lua_State
*
L
,
ROTable
*
tab
,
TValue
*
key
,
TValue
*
val
);
void
*
luaR_getmeta
(
ROTable
*
tab
);
int
luaR_isrotable
(
void
*
p
);
/*
* Set inRO check depending on platform. Note that this implementation needs
* to work on both the host (luac.cross) and ESP targets. The luac.cross
* VM is used for the -e option, and is primarily used to be able to debug
* VM changes on the more developer-friendly hot gdb environment.
*/
#if defined(LUA_CROSS_COMPILER)
#if defined(__CYGWIN__)
#define _RODATA_END __end__
#else
#define luaR_isrotable(p) (0)
#define _RODATA_END _edata
#endif
extern
const
char
_RODATA_END
[];
#define IN_RODATA_AREA(p) (((const char *)(p)) < _RODATA_END)
#else
/* xtensa tool chain for ESP target */
extern
const
char
_irom0_text_start
[];
extern
const
char
_irom0_text_end
[];
#define IN_RODATA_AREA(p) (((const char *)(p)) >= _irom0_text_start && ((const char *)(p)) <= _irom0_text_end)
#endif
/* Return 1 if the given pointer is a rotable */
#define luaR_isrotable(p) IN_RODATA_AREA(p)
#endif
app/lua/lstring.c
View file @
11592951
...
...
@@ -80,16 +80,12 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return
ts
;
}
#ifdef LUA_CROSS_COMPILER
#define IN_RO_AREA(p) (0)
#else
/* xtensa tool chain for ESP */
extern
char
_irom0_text_start
[];
extern
char
_irom0_text_end
[];
#define IN_RO_AREA(p) ((p) >= _irom0_text_start && (p) <= _irom0_text_end)
static
int
lua_is_ptr_in_ro_area
(
const
char
*
p
)
{
#ifdef LUA_CROSS_COMPILER
return
0
;
// TStrings are never in RO in luac.cross
#else
return
IN_RODATA_AREA
(
p
);
#endif
int
lua_is_ptr_in_ro_area
(
const
char
*
p
)
{
return
IN_RO_AREA
(
p
);
}
/*
...
...
app/lua/lstring.h
View file @
11592951
...
...
@@ -13,7 +13,7 @@
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+(testbit(
(s)->
marked, READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizestring(s) (sizeof(union TString)+(testbit(
get
marked
(s)
, READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
...
...
app/lua/lstrlib.c
View file @
11592951
...
...
@@ -15,7 +15,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
...
...
app/lua/ltable.c
View file @
11592951
...
...
@@ -580,7 +580,7 @@ const TValue *luaH_getnum (Table *t, int key) {
/* same thing for rotables */
const
TValue
*
luaH_getnum_ro
(
void
*
t
,
int
key
)
{
const
TValue
*
res
=
luaR_findentry
(
t
,
NULL
,
key
,
NULL
);
const
TValue
*
res
=
luaR_findentry
N
(
t
,
key
,
NULL
);
return
res
?
res
:
luaO_nilobject
;
}
...
...
@@ -599,14 +599,10 @@ const TValue *luaH_getstr (Table *t, TString *key) {
}
/* same thing for rotables */
const
TValue
*
luaH_getstr_ro
(
void
*
t
,
TString
*
key
)
{
char
keyname
[
LUA_MAX_ROTABLE_NAME
+
1
];
const
TValue
*
res
;
if
(
!
t
)
const
TValue
*
luaH_getstr_ro
(
void
*
t
,
TString
*
key
)
{
if
(
!
t
||
key
->
tsv
.
len
>
LUA_MAX_ROTABLE_NAME
)
return
luaO_nilobject
;
luaR_getcstr
(
keyname
,
key
,
LUA_MAX_ROTABLE_NAME
);
res
=
luaR_findentry
(
t
,
keyname
,
0
,
NULL
);
return
res
?
res
:
luaO_nilobject
;
return
luaR_findentry
(
t
,
key
,
NULL
);
}
...
...
@@ -745,7 +741,7 @@ int luaH_getn (Table *t) {
int
luaH_getn_ro
(
void
*
t
)
{
int
i
=
1
,
len
=
0
;
while
(
luaR_findentry
(
t
,
NULL
,
i
++
,
NULL
))
while
(
luaR_findentry
N
(
t
,
i
++
,
NULL
))
len
++
;
return
len
;
}
...
...
app/lua/ltablib.c
View file @
11592951
...
...
@@ -13,7 +13,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
...
...
app/lua/ltm.c
View file @
11592951
...
...
@@ -50,14 +50,22 @@ void luaT_init (lua_State *L) {
** tag methods
*/
const
TValue
*
luaT_gettm
(
Table
*
events
,
TMS
event
,
TString
*
ename
)
{
const
TValue
*
tm
=
luaR_isrotable
(
events
)
?
luaH_getstr_ro
(
events
,
ename
)
:
luaH_getstr
(
events
,
ename
);
const
TValue
*
tm
;
lua_assert
(
event
<=
TM_EQ
);
if
(
ttisnil
(
tm
))
{
/* no tag method? */
if
(
!
luaR_isrotable
(
events
))
if
(
luaR_isrotable
(
events
))
{
tm
=
luaH_getstr_ro
(
events
,
ename
);
if
(
ttisnil
(
tm
))
{
/* no tag method? */
return
NULL
;
}
}
else
{
tm
=
luaH_getstr
(
events
,
ename
);
if
(
ttisnil
(
tm
))
{
/* no tag method? */
events
->
flags
|=
cast_byte
(
1u
<<
event
);
/* cache this fact */
return
NULL
;
}
else
return
tm
;
return
NULL
;
}
}
return
tm
;
}
...
...
app/lua/ltm.h
View file @
11592951
...
...
@@ -9,7 +9,7 @@
#include "lobject.h"
#include "lrotable.h"
/*
* WARNING: if you change the order of this enumeration,
...
...
@@ -36,12 +36,10 @@ typedef enum {
TM_N
/* number of elements in the enum */
}
TMS
;
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
!luaR_isrotable(et) && ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
(
!luaR_isrotable(et) && ((et)->flags & (1u<<(e)))
)
? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l,et,e)
gfasttm(G(l), et, e)
#define fasttm(l,et,e)
gfasttm(G(l), et, e)
LUAI_DATA
const
char
*
const
luaT_typenames
[];
...
...
app/lua/luac_cross/Makefile
View file @
11592951
#
# This Make file is called from the core Makefile hierarchy w
hic
h is a hierarchical
# make which uses parent callbacks to implement inheritance. However i
f
luac_cross
# build stands outside this
it
uses the host toolchain to implement a separate
# This Make file is called from the core Makefile hierarchy w
it
h is a hierarchical
# make
w
which uses parent callbacks to implement inheritance. However i
s
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
../../lib
c
CCFLAGS
:=
-I
..
-I
../../include
-I
../../
libc
-I
../../
uz
lib
LDFLAGS
:=
-L
$(SDK_DIR)
/lib
-L
$(SDK_DIR)
/ld
-lm
-ldl
-Wl
,-Map
=
mapfile
CCFLAGS
+=
-Wall
...
...
@@ -18,6 +18,7 @@ TARGET = host
ifeq
($(FLAVOR),debug)
CCFLAGS
+=
-O0
-g
TARGET_LDFLAGS
+=
-O0
-g
DEFINES
+=
-DLUA_DEBUG_BUILD
else
FLAVOR
=
release
CCFLAGS
+=
-O2
...
...
@@ -31,13 +32,13 @@ LUASRC := lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.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
UZSRC
:=
uzlib_deflate.c crc32.c
#
# This relies on the files being unique on the vpath
#
SRC
:=
$(LUACSRC)
$(LUASRC)
$(LIBCSRC)
vpath %.c .
:
..:../../libc
SRC
:=
$(LUACSRC)
$(LUASRC)
$(LIBCSRC)
$(UZSRC)
vpath %.c .
:
..:../../libc:../../uzlib
ODIR
:=
.output/
$(TARGET)
/
$(FLAVOR)
/obj
...
...
@@ -51,12 +52,7 @@ CC := $(WRAPCC) gcc
ECHO
:=
echo
BUILD_TYPE
:=
$(
shell
$(CC)
$(EXTRA_CCFLAGS)
-E
-dM
- <../../../app/include/user_config.h |
grep
LUA_NUMBER_INTEGRAL |
wc
-l
)
ifeq
($(BUILD_TYPE),0)
IMAGE
:=
../../../luac.cross
else
IMAGE
:=
../../../luac.cross.int
endif
.PHONY
:
test clean all
...
...
@@ -70,7 +66,6 @@ test :
@
echo
SRC:
$(SRC)
@
echo
OBJS:
$(OBJS)
@
echo
DEPS:
$(DEPS)
@
echo
IMAGE:
$(IMAGE)
clean
:
$(RM)
-r
$(ODIR)
...
...
app/lua/luac_cross/lflashimg.c
View file @
11592951
/*
/*
**--
** lflashimg.c
** Dump a compiled Proto hiearchy to a RO (FLash) image file
** See Copyright Notice in lua.h
...
...
@@ -19,6 +19,7 @@
#undef LUA_FLASH_STORE
#define LUA_FLASH_STORE
#include "lflash.h"
#include "uzlib.h"
//#define LOCAL_DEBUG
...
...
@@ -46,18 +47,18 @@ typedef unsigned int uint;
* 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:
* word aligned, and any address references within the LFS are also word-aligned.
*
* 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.
* This version adds gzip compression of the generated LFS image for more efficient
* over-the-air (OTA) transfer, so the method of tagging address words has been
* replaced by a scheme which achieves better compression: an additional bitmap
* has been added to the image, with each bit corresponding to a word in the image
* and set if the corresponding work is an address. The addresses are stored as
* signed relative word offsets.
*
* 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 unloader is documented in lflash.c Note that his relocation 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
*
...
...
@@ -66,7 +67,7 @@ typedef unsigned int uint;
* 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.
*
* A
L
so note that image built with a given LUA_PACK_TVALUES / LUA_NUNBER_INTEGRAL
* A
l
so 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.
*
...
...
@@ -96,8 +97,19 @@ typedef struct flashts { /* This is the fixed 32-bit equivalent of TString
#endif
static
uint
curOffset
=
0
;
static
uint
flashImage
[
LUA_MAX_FLASH_SIZE
];
static
unsigned
char
flashAddrTag
[
LUA_MAX_FLASH_SIZE
/
WORDSIZE
];
/*
* The flashAddrTag is a bit array, one bit per flashImage word denoting
* whether the corresponding word is a relative address. The defines
* are access methods for this bit array.
*/
static
uint
flashImage
[
LUA_MAX_FLASH_SIZE
+
LUA_MAX_FLASH_SIZE
/
32
];
static
uint
*
flashAddrTag
=
flashImage
+
LUA_MAX_FLASH_SIZE
;
#define _TW(v) (v)>>5
#define _TB(v) (1<<((v)&0x1F))
#define setFlashAddrTag(v) flashAddrTag[_TW(v)] |= _TB(v)
#define getFlashAddrTag(v) ((flashAddrTag[_TW(v)]&_TB(v)) != 0)
#define fatal luac_fatal
extern
void
__attribute__
((
noreturn
))
luac_fatal
(
const
char
*
message
);
...
...
@@ -115,7 +127,7 @@ 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 mem
m
ory"
);
fatal
(
"Out of Flash memory"
);
}
return
p
;
}
...
...
@@ -128,8 +140,8 @@ static void *flashAlloc(lua_State* L, size_t n) {
#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
&
(
WORDSIZE
-
1
)));
// check word aligned
doffset
>>=
WORDSHIFT
;
// and convert to a word offset
lua_assert
(
doffset
<=
curOffset
);
if
(
p
)
{
uint
poffset
=
cast
(
char
*
,
p
)
-
cast
(
char
*
,
flashImage
);
...
...
@@ -137,10 +149,8 @@ static void _toFlashAddr(lua_State* L, FlashAddr *a, void *p) {
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
;
}
setFlashAddrTag
(
doffset
);
// And tag as an address
}
/* else leave clear */
// Special case for NULL pointer
}
/*
...
...
@@ -231,7 +241,7 @@ static void createROstrt(lua_State *L, FlashHeader *fh) {
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
memcpy
(
flashAlloc
(
L
,
len
+
1
),
p
,
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
...
...
@@ -308,6 +318,9 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
case
'I'
:
*
d
++
=
*
s
++
;
break
;
case
'H'
:
*
d
++
=
(
*
s
++
)
&
0
;
break
;
case
'S'
:
newts
=
resolveTString
(
L
,
*
cast
(
TString
**
,
s
));
toFlashAddr
(
L
,
*
d
,
newts
);
...
...
@@ -318,11 +331,15 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
/* This code has to work for both Integer and Float build variants */
memset
(
d
,
0
,
TARGET_TV_SIZE
);
TValue
*
sv
=
cast
(
TValue
*
,
s
);
/* The value is 0, 4 or 8 bytes depending on type */
if
(
ttisstring
(
sv
))
{
toFlashAddr
(
L
,
*
d
,
resolveTString
(
L
,
rawtsvalue
(
sv
)));
}
else
{
/* non-collectable types all of size lua_Number */
lua_assert
(
!
iscollectable
(
sv
));
}
else
if
(
ttisnumber
(
sv
))
{
*
cast
(
lua_Number
*
,
d
)
=
*
cast
(
lua_Number
*
,
s
);
}
else
if
(
!
ttisnil
(
sv
)){
/* all other types are 4 byte */
lua_assert
(
!
iscollectable
(
sv
));
*
cast
(
uint
*
,
d
)
=
*
cast
(
uint
*
,
s
);
}
*
cast
(
int
*
,
cast
(
lua_Number
*
,
d
)
+
1
)
=
ttype
(
sv
);
s
+=
FLASH_WORDS
(
TValue
);
...
...
@@ -338,9 +355,9 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
/* The debug optimised version has a different Proto layout */
#ifdef LUA_OPTIMIZE_DEBUG
#define PROTO_COPY_MASK "A
I
AAAAAASIIIIIIIAI"
#define PROTO_COPY_MASK "A
H
AAAAAASIIIIIIIAI"
#else
#define PROTO_COPY_MASK "A
I
AAAAAASIIIIIIIIAI"
#define PROTO_COPY_MASK "A
H
AAAAAASIIIIIIIIAI"
#endif
/*
...
...
@@ -378,44 +395,52 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
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
)
{
void
*
data
,
int
strip
,
lu_int32
address
,
lu_int32
maxSize
)
{
// parameter strip is ignored for now
lua_newtable
(
L
);
FlashHeader
*
fh
=
cast
(
FlashHeader
*
,
flashAlloc
(
L
,
sizeof
(
FlashHeader
)));
int
i
,
status
;
lua_newtable
(
L
);
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
);
if
(
fh
->
flash_size
>
maxSize
)
{
fatal
(
"The image is too large for specfied LFS size"
);
}
if
(
address
)
{
/* in absolute mode convert addresses to mapped address */
for
(
i
=
0
;
i
<
curOffset
;
i
++
)
if
(
getFlashAddrTag
(
i
))
flashImage
[
i
]
=
4
*
flashImage
[
i
]
+
address
;
lua_unlock
(
L
);
status
=
w
(
L
,
flashImage
,
fh
->
flash_size
,
data
);
}
else
{
/* compressed PI mode */
/*
* In image mode, shift the relocation bitmap down directly above
* the used flashimage. This consolidated array is then gzipped.
*/
uint
oLen
;
uint8_t
*
oBuf
;
int
bmLen
=
sizeof
(
uint
)
*
((
curOffset
+
31
)
/
32
);
/* 32 flags to a word */
memmove
(
flashImage
+
curOffset
,
flashAddrTag
,
bmLen
);
status
=
uzlib_compress
(
&
oBuf
,
&
oLen
,
(
const
uint8_t
*
)
flashImage
,
bmLen
+
fh
->
flash_size
);
if
(
status
!=
UZLIB_OK
)
{
luac_fatal
(
"Out of memory during image compression"
);
}
lua_unlock
(
L
);
#if 0
status = w(L, flashImage, bmLen+fh->flash_size, data);
#else
status
=
w
(
L
,
oBuf
,
oLen
,
data
);
free
(
oBuf
);
#endif
}
lua_lock
(
L
);
return
status
;
}
app/lua/luac_cross/liolib.c
View file @
11592951
...
...
@@ -18,7 +18,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
...
...
@@ -28,7 +27,11 @@
#define LUA_IO_SETFIELD(f) lua_rawseti(L, LUA_REGISTRYINDEX,(int)(liolib_keys[f]))
/* "Pseudo-random" keys for the registry */
static
const
size_t
liolib_keys
[]
=
{(
size_t
)
&
luaL_callmeta
,
(
size_t
)
&
luaL_typerror
,
(
size_t
)
&
luaL_argerror
};
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"
};
...
...
@@ -452,20 +455,6 @@ const LUA_REG_TYPE iolib_funcs[] = {
{
LNILKEY
,
LNILVAL
}
};
/* 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"
,
io_index
},
{
NULL
,
NULL
}
};
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrodefs.h"
const
LUA_REG_TYPE
flib
[]
=
{
{
LSTRKEY
(
"close"
),
LFUNCVAL
(
io_close
)},
...
...
@@ -481,6 +470,7 @@ const LUA_REG_TYPE flib[] = {
{
LNILKEY
,
LNILVAL
}
};
static
const
luaL_Reg
io_base
[]
=
{{
NULL
,
NULL
}};
static
void
createstdfile
(
lua_State
*
L
,
FILE
*
f
,
int
k
,
const
char
*
fname
)
{
*
newfile
(
L
)
=
f
;
...
...
@@ -490,14 +480,18 @@ static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
lua_setfield
(
L
,
-
2
,
fname
);
}
LUALIB_API
int
luaopen_io
(
lua_State
*
L
)
{
luaL_rometatable
(
L
,
LUA_FILEHANDLE
,
(
void
*
)
flib
);
/* create metatable for file handles */
luaL_register_light
(
L
,
LUA_IOLIBNAME
,
io
lib
);
LUALIB_API
int
luaopen_io
(
lua_State
*
L
)
{
luaL_rometatable
(
L
,
LUA_FILEHANDLE
,
(
void
*
)
flib
);
/* create metatable for file handles */
luaL_register_light
(
L
,
LUA_IOLIBNAME
,
io
_base
);
lua_pushvalue
(
L
,
-
1
);
lua_setmetatable
(
L
,
-
2
);
lua_pushliteral
(
L
,
"__index"
);
lua_pushrotable
(
L
,
(
void
*
)
iolib_funcs
);
lua_rawset
(
L
,
-
3
);
/* create (and set) default files */
createstdfile
(
L
,
stdin
,
IO_INPUT
,
"stdin"
);
createstdfile
(
L
,
stdout
,
IO_OUTPUT
,
"stdout"
);
createstdfile
(
L
,
stderr
,
0
,
"stderr"
);
createstdfile
(
L
,
stderr
,
IO_STDERR
,
"stderr"
);
return
1
;
}
app/lua/luac_cross/loslib.c
View file @
11592951
...
...
@@ -20,8 +20,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
static
int
os_pushresult
(
lua_State
*
L
,
int
i
,
const
char
*
filename
)
{
int
en
=
errno
;
/* calls to Lua API may change this value */
...
...
app/lua/luac_cross/luac.c
View file @
11592951
...
...
@@ -35,6 +35,7 @@ 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
lu_int32
maxSize
=
0x40000
;
/* maximuum uncompressed image size */
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 */
...
...
@@ -72,6 +73,7 @@ static void usage(const char* message)
" -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
"
" -m size maximum LFS image in bytes
\n
"
" -p parse only
\n
"
" -s strip debug information
\n
"
" -v show version information
\n
"
...
...
@@ -123,6 +125,13 @@ static int doargs(int argc, char* argv[])
lookup
=
1
;
else
if
(
IS
(
"-l"
))
/* list */
++
listing
;
else
if
(
IS
(
"-m"
))
/* specify a maximum image size */
{
flash
=
lookup
=
1
;
maxSize
=
strtol
(
argv
[
++
i
],
NULL
,
0
);
if
(
maxSize
&
0xFFF
)
usage
(
LUA_QL
(
"-e"
)
" maximum size must be a multiple of 4,096"
);
}
else
if
(
IS
(
"-o"
))
/* output file */
{
output
=
argv
[
++
i
];
...
...
@@ -264,7 +273,8 @@ struct Smain {
};
extern
uint
dumpToFlashImage
(
lua_State
*
L
,
const
Proto
*
main
,
lua_Writer
w
,
void
*
data
,
int
strip
,
lu_int32
address
);
void
*
data
,
int
strip
,
lu_int32
address
,
lu_int32
maxSize
);
static
int
pmain
(
lua_State
*
L
)
{
...
...
@@ -302,7 +312,7 @@ static int pmain(lua_State* L)
lua_lock
(
L
);
if
(
flash
)
{
result
=
dumpToFlashImage
(
L
,
f
,
writer
,
D
,
stripping
,
address
);
result
=
dumpToFlashImage
(
L
,
f
,
writer
,
D
,
stripping
,
address
,
maxSize
);
}
else
{
result
=
luaU_dump_crosscompile
(
L
,
f
,
writer
,
D
,
stripping
,
target
);
...
...
app/lua/luaconf.h
View file @
11592951
...
...
@@ -896,13 +896,6 @@ union luai_Cast { double l_d; long l_l; };
** without modifying the main part of the file.
*/
/* 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)
#define LUA_META_ROTABLES
#endif
#if LUA_OPTIMIZE_MEMORY == 2 && defined(LUA_USE_POPEN)
#error "Pipes not supported in aggresive optimization mode (LUA_OPTIMIZE_MEMORY=2)"
#endif
...
...
app/lua/lvm.c
View file @
11592951
...
...
@@ -130,18 +130,29 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
TValue
temp
;
for
(
loop
=
0
;
loop
<
MAXTAGLOOP
;
loop
++
)
{
const
TValue
*
tm
;
if
(
ttistable
(
t
)
||
ttisrotable
(
t
))
{
/* `t' is a table? */
void
*
h
=
ttistable
(
t
)
?
hvalue
(
t
)
:
rvalue
(
t
);
const
TValue
*
res
=
ttistable
(
t
)
?
luaH_get
((
Table
*
)
h
,
key
)
:
luaH_get_ro
(
h
,
key
);
/* do a primitive get */
if
(
ttistable
(
t
))
{
/* `t' is a table? */
Table
*
h
=
hvalue
(
t
);
const
TValue
*
res
=
luaH_get
(
h
,
key
);
/* do a primitive get */
if
(
!
ttisnil
(
res
)
||
/* result is no nil? */
(
tm
=
fasttm
(
L
,
ttistable
(
t
)
?
((
Table
*
)
h
)
->
metatable
:
(
Table
*
)
luaR_getmeta
(
h
)
,
TM_INDEX
))
==
NULL
)
{
/* or no TM? */
(
tm
=
fasttm
(
L
,
h
->
metatable
,
TM_INDEX
))
==
NULL
)
{
/* or no TM? */
setobj2s
(
L
,
val
,
res
);
return
;
}
}
/* else will try the tag method */
}
else
if
(
ttisrotable
(
t
))
{
/* `t' is a table? */
void
*
h
=
rvalue
(
t
);
const
TValue
*
res
=
luaH_get_ro
(
h
,
key
);
/* do a primitive get */
if
(
!
ttisnil
(
res
)
||
/* result is no nil? */
(
tm
=
fasttm
(
L
,
(
Table
*
)
luaR_getmeta
(
h
),
TM_INDEX
))
==
NULL
)
{
/* or no TM? */
setobj2s
(
L
,
val
,
res
);
return
;
}
/* else will try the tag method */
}
else
if
(
ttisnil
(
tm
=
luaT_gettmbyobj
(
L
,
t
,
TM_INDEX
)))
luaG_typeerror
(
L
,
t
,
"index"
);
if
(
ttisfunction
(
tm
)
||
ttislightfunction
(
tm
))
{
callTMres
(
L
,
val
,
tm
,
t
,
key
);
return
;
...
...
@@ -161,25 +172,27 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
L
->
top
++
;
fixedstack
(
L
);
for
(
loop
=
0
;
loop
<
MAXTAGLOOP
;
loop
++
)
{
const
TValue
*
tm
;
if
(
ttistable
(
t
)
||
ttisrotable
(
t
))
{
/* `t' is a table? */
void
*
h
=
ttistable
(
t
)
?
hvalue
(
t
)
:
rvalue
(
t
);
TValue
*
oldval
=
ttistable
(
t
)
?
luaH_set
(
L
,
(
Table
*
)
h
,
key
)
:
NULL
;
/* do a primitive set */
if
((
oldval
&&
!
ttisnil
(
oldval
))
||
/* result is no nil? */
(
tm
=
fasttm
(
L
,
ttistable
(
t
)
?
((
Table
*
)
h
)
->
metatable
:
(
Table
*
)
luaR_getmeta
(
h
),
TM_NEWINDEX
))
==
NULL
)
{
/* or no TM? */
if
(
oldval
)
{
L
->
top
--
;
unfixedstack
(
L
);
setobj2t
(
L
,
oldval
,
val
);
((
Table
*
)
h
)
->
flags
=
0
;
luaC_barriert
(
L
,
(
Table
*
)
h
,
val
);
}
const
TValue
*
tm
=
NULL
;
if
(
ttistable
(
t
))
{
/* `t' is a table? */
Table
*
h
=
hvalue
(
t
);
TValue
*
oldval
=
luaH_set
(
L
,
h
,
key
);
/* do a primitive set */
if
((
!
ttisnil
(
oldval
))
||
/* result is no nil? */
(
tm
=
fasttm
(
L
,
h
->
metatable
,
TM_NEWINDEX
))
==
NULL
)
{
L
->
top
--
;
unfixedstack
(
L
);
setobj2t
(
L
,
oldval
,
val
);
((
Table
*
)
h
)
->
flags
=
0
;
luaC_barriert
(
L
,
(
Table
*
)
h
,
val
);
return
;
}
/* else will try the tag method */
}
else
if
(
ttisrotable
(
t
))
{
luaG_runerror
(
L
,
"invalid write to ROM variable"
);
}
else
if
(
ttisnil
(
tm
=
luaT_gettmbyobj
(
L
,
t
,
TM_NEWINDEX
)))
luaG_typeerror
(
L
,
t
,
"index"
);
if
(
ttisfunction
(
tm
)
||
ttislightfunction
(
tm
))
{
L
->
top
--
;
unfixedstack
(
L
);
...
...
@@ -294,7 +307,7 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
case
LUA_TBOOLEAN
:
return
bvalue
(
t1
)
==
bvalue
(
t2
);
/* true must be 1 !! */
case
LUA_TROTABLE
:
return
rvalue
(
t1
)
==
rvalue
(
t2
);
case
LUA_TLIGHTUSERDATA
:
case
LUA_TLIGHTUSERDATA
:
case
LUA_TLIGHTFUNCTION
:
return
pvalue
(
t1
)
==
pvalue
(
t2
);
case
LUA_TUSERDATA
:
{
...
...
@@ -321,7 +334,7 @@ void luaV_concat (lua_State *L, int total, int last) {
if
(
G
(
L
)
->
memlimit
<
max_sizet
)
max_sizet
=
G
(
L
)
->
memlimit
;
do
{
/* Any call which does a memory allocation may trim the stack,
invalidating top unless the stack is fixed duri
ng the allocation */
invalidating top unless the stack is fixed during the allocation */
StkId
top
=
L
->
base
+
last
+
1
;
fixedstack
(
L
);
int
n
=
2
;
/* number of elements handled in this pass (at least 2) */
...
...
@@ -570,7 +583,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
case
OP_LEN
:
{
const
TValue
*
rb
=
RB
(
i
);
switch
(
ttype
(
rb
))
{
case
LUA_TTABLE
:
case
LUA_TTABLE
:
case
LUA_TROTABLE
:
{
setnvalue
(
ra
,
ttistable
(
rb
)
?
cast_num
(
luaH_getn
(
hvalue
(
rb
)))
:
cast_num
(
luaH_getn_ro
(
rvalue
(
rb
))));
break
;
...
...
Prev
1
2
3
4
5
6
7
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