Compare commits

..

87 Commits

Author SHA1 Message Date
Roberto Ierusalimschy
a1415c0d72 bug in order NaN x int (tests must ensure that NaN does not get
converted to integer)
2015-06-09 12:53:35 -03:00
Roberto Ierusalimschy
2ecaf18138 using macros ('rttype' and 'settt_') to access "private" field 'tt_' 2015-06-09 11:21:42 -03:00
Roberto Ierusalimschy
cbef15f3ea comment (FALLTHROUGH position) 2015-06-09 11:21:13 -03:00
Roberto Ierusalimschy
16e8bb360b comment 2015-06-09 11:21:00 -03:00
Roberto Ierusalimschy
6628012e9e new release number (5.3.1) 2015-06-03 10:03:38 -03:00
Roberto Ierusalimschy
ed1fe28bb8 When comparing integers with floats, use float as common type when
possible (i.e., when integer fits in a float without losses); seems
to be more efficient in architectures with native support for used
Lua numbers
2015-06-02 16:11:24 -03:00
Roberto Ierusalimschy
6645bb2df4 'strcache' elements as arrays of 1 element hints that cache can
be n-way (instead of direct mapped)
2015-06-01 13:34:37 -03:00
Roberto Ierusalimschy
02aed045de bug: return hook may not see correct values for active local variables
when function returns
2015-05-22 16:32:42 -03:00
Roberto Ierusalimschy
72bd2ef6c5 dependencies updated 2015-05-22 16:29:43 -03:00
Roberto Ierusalimschy
d39bb51faa bug: interpreter cannot pop activation frame before calling return
hook (as it may want to access local variables active by the end
of the function)
2015-05-22 14:48:19 -03:00
Roberto Ierusalimschy
6142e663e4 reuse of 'addinfo' by lexical errors 2015-05-22 14:45:56 -03:00
Roberto Ierusalimschy
6dc20ff293 'l <= r' for numbers has its own function, instead of using
'not (r < l)' (seems to be slightly more efficient)
2015-05-20 15:19:11 -03:00
Roberto Ierusalimschy
99391e24ea new configuration macro 'l_mathlim' (simplifies some dependencies
on float type)
2015-05-20 14:39:23 -03:00
Roberto Ierusalimschy
0ec12c1bd1 new semantics for numerical order (following math regardless
representation)
2015-05-20 13:22:55 -03:00
Roberto Ierusalimschy
a71c0ab861 detail (removed useless '#include') 2015-05-20 13:22:30 -03:00
Roberto Ierusalimschy
04ba6ea83b new semantics for equality int-float 2015-04-29 15:27:16 -03:00
Roberto Ierusalimschy
a1935b9cba error message ("too complex" -> "too many registers") + MAXREGS
changed to 255 (no reason not to use maximum allowed)
2015-04-29 15:24:11 -03:00
Roberto Ierusalimschy
513c639bf9 patch for last bug corrected to be against last released version
(and not against last version in RCS...)
2015-04-13 13:13:25 -03:00
Roberto Ierusalimschy
69b5f7a410 some details in 'luaO_int2fb' + more consistent use of the locale
decimal point
2015-04-11 15:30:08 -03:00
Roberto Ierusalimschy
ae76c39712 Bug: suspended '__le' metamethod can give wrong result 2015-04-10 14:56:25 -03:00
Roberto Ierusalimschy
0d4a1f71db re-organization of initial configuration options 2015-04-10 14:41:04 -03:00
Roberto Ierusalimschy
67bf789462 avoid using API functions inside the core 2015-04-06 09:23:48 -03:00
Roberto Ierusalimschy
48d0674c2e more consistent use of locale radix character across Lua 2015-04-03 15:41:57 -03:00
Roberto Ierusalimschy
6ffe006f5c detail (removed unused macro VARBITS) 2015-04-02 18:10:53 -03:00
Roberto Ierusalimschy
4998e852ec new function 'log2' to test 'luaO_ceillog2' (if needed) 2015-04-02 18:10:21 -03:00
Roberto Ierusalimschy
65ac789565 detail (comment) 2015-04-02 18:09:51 -03:00
Roberto Ierusalimschy
cfc84c856d 'LUA_REAL_*' -> 'LUA_FLOAT_*' (everywhere else we are using 'float') 2015-03-31 09:00:07 -03:00
Roberto Ierusalimschy
63720a4290 janitor work (comments, variable names, some other details) 2015-03-30 16:51:00 -03:00
Roberto Ierusalimschy
484bf14a6b calls to 'luaC_checkGC' in luaD_precall moved near to 'luaD_checkstack'
(which is what can need memory)
2015-03-30 13:05:23 -03:00
Roberto Ierusalimschy
abb2f5511d detail ('b + base' -> 'base + b' to follow all other similar uses) 2015-03-30 12:45:01 -03:00
Roberto Ierusalimschy
fcc6e1220e avoid expression with side effect (in debug mode) inside 'sizeof' 2015-03-30 12:43:51 -03:00
Roberto Ierusalimschy
3a91274547 details (avoid 'lint' warnings) 2015-03-30 12:42:59 -03:00
Roberto Ierusalimschy
f2a813ae10 details (avoid some 'lint' warnings) 2015-03-28 16:16:55 -03:00
Roberto Ierusalimschy
e723c75c02 details (avoid 'lint' warnings) 2015-03-28 16:14:47 -03:00
Roberto Ierusalimschy
b436ed58a3 'clearapihash' -> 'luaS_clearcache' and moved to 'lstring.c' (which
keeps all code related to this cache)
2015-03-25 10:42:19 -03:00
Roberto Ierusalimschy
2b37f2150e comments 2015-03-14 14:58:57 -03:00
Roberto Ierusalimschy
331632e8d8 code detail ('if' -> '?:') 2015-03-13 13:24:50 -03:00
Roberto Ierusalimschy
7d930ec694 use 'log2' when available 2015-03-12 11:04:04 -03:00
Roberto Ierusalimschy
0cf3b6495a 'ci_func' don't need to be exported 2015-03-11 13:10:41 -03:00
Roberto Ierusalimschy
b66fedadae 'lua_pushliteral' implemented with 'lua_pushstring' (to take
advantage of the cache)
2015-03-10 11:17:51 -03:00
Roberto Ierusalimschy
fd6e680e21 detail 2015-03-10 11:15:06 -03:00
Roberto Ierusalimschy
57c0db219b line history keep lines without added 'return' 2015-03-09 18:57:05 -03:00
Roberto Ierusalimschy
4ba0cb4580 always use macros to operate on lua_Numbers 2015-03-07 16:30:16 -03:00
Roberto Ierusalimschy
a30c66f0fc macro 'luai_apicheck'/'api_check' back with a 'lua_State' parameter
(some people use it)
2015-03-06 16:49:50 -03:00
Roberto Ierusalimschy
bb4baa73ea allocation function is not exactly API (and cannot raise errors
like other API functions); better not use 'api_check' for cheking it.
2015-03-06 16:45:54 -03:00
Roberto Ierusalimschy
d7d44b038d detail (use 'lua_pushliteral' to push an empty string) 2015-03-06 16:09:08 -03:00
Roberto Ierusalimschy
297512b34c avoid using 'lua_pushliteral' in a non-zero-terminated string 2015-03-05 13:07:46 -03:00
Roberto Ierusalimschy
2ae2e6408e avoid testing for NULL when marking objects that cannot be NULL 2015-03-04 10:51:55 -03:00
Roberto Ierusalimschy
a80cada914 new cache for interning strings 2015-03-04 10:31:21 -03:00
Roberto Ierusalimschy
a00013c8d0 'point2int' -> 'point2uint' (to reflect its actual result type) 2015-03-03 16:53:13 -03:00
Roberto Ierusalimschy
b9a1f27250 do not attempt emergency collection while building state (it is
useless, and state can be inconsistent)
2015-03-03 15:18:29 -03:00
Roberto Ierusalimschy
29aed28802 detail (use 'luaS_newliteral' when possible) 2015-03-03 15:17:04 -03:00
Roberto Ierusalimschy
951b562cf8 configuration for numerical types through only one #define for
each type
2015-03-02 13:59:01 -03:00
Roberto Ierusalimschy
6408bc0b7f new macros 'chgfltvalue'/'chgivalue' (numerical for loop does
not need to set the type of its internal variable at each iteration)
2015-03-02 13:04:52 -03:00
Roberto Ierusalimschy
91efb4b895 LUA_COMPAT_5_1 needs some options deprecated from 5.2 to 5.3 2015-02-28 16:22:31 -03:00
Roberto Ierusalimschy
27c5b1b237 added patches to two bugs 2015-02-23 16:20:43 -03:00
Roberto Ierusalimschy
d51bdc166d bug: 'string.format("%f")' can cause a buffer overflow (with long doubles)
bug: 'debug.getlocal' on a coroutine suspended in a hook can crash
the interpreter
2015-02-20 16:21:29 -02:00
Roberto Ierusalimschy
81245b1ad5 'numisinteger' (for table keys) replaced by 'luaV_tointeger' (old
'tointeger_aux'), which can do the same job.
2015-02-20 12:27:53 -02:00
Roberto Ierusalimschy
397ce11996 make 'hashfloat' configurable 2015-02-20 12:05:01 -02:00
Roberto Ierusalimschy
97f2aa5a44 bug: when manipulating other threads, there is no garanties about
their stack space
2015-02-19 15:06:21 -02:00
Roberto Ierusalimschy
419e2cb01d detail (file does not need 'string.h') 2015-02-16 11:15:00 -02:00
Roberto Ierusalimschy
374f6c4612 detail ('fopen' needs 'stdio.h') 2015-02-16 11:14:33 -02:00
Roberto Ierusalimschy
4bdf9962bf bug: suspended function can have its 'func' field not pointing to
its function, crashing debug functions
2015-02-13 14:01:17 -02:00
Roberto Ierusalimschy
e0306e386f some changes in 'hashfloat' to avoid undefined (in ISO C) numerical
conversions
2015-02-13 11:05:34 -02:00
Roberto Ierusalimschy
2e6e53c7cc added API checks to some unprotected 'top' increments 2015-02-11 16:47:22 -02:00
Roberto Ierusalimschy
2a57d2346e detail 2015-02-09 16:05:46 -02:00
Roberto Ierusalimschy
7e425be975 bug (in 5.2): Chunk with too many lines can seg. fault 2015-02-09 15:57:45 -02:00
Roberto Ierusalimschy
0705e7b39f detail (no need to write 'double' in source) 2015-02-09 15:41:54 -02:00
Roberto Ierusalimschy
4ccc4578b3 detail (use 'l_floor' instead of 'l_mathop(floor)') 2015-02-09 13:41:56 -02:00
Roberto Ierusalimschy
5e8c162b6c detail 2015-02-05 15:50:24 -02:00
Roberto Ierusalimschy
c8d6cb0136 macros 'luai_num*' (for float arithmetic operations) moved to
llimits.h.
2015-02-05 15:15:33 -02:00
Roberto Ierusalimschy
0edcdf49c0 added comments documenting LUA_NOCVTN2S/LUA_NOCVTS2N 2015-02-05 14:53:34 -02:00
Roberto Ierusalimschy
b7dfd18612 make buffer for format specification a little larger (length modifier
can be larger than 2, e.g. "I64")
2015-02-04 10:54:31 -02:00
Roberto Ierusalimschy
8efcd411fe own implementation for 'string.format("%a")' for C89 platforms 2015-02-04 10:52:57 -02:00
Roberto Ierusalimschy
90d016980f detail ('luaL_getmetatable' does not return a boolean, but a tag) 2015-02-03 15:38:24 -02:00
Roberto Ierusalimschy
b3996c55f6 LUAL_BUFFERSIZE affects the API, so it is better not to change it
between releases of the same version. (The long double case seems
to be too rare, so that should not be a problem; moreover, that
case is related to a bug)
2015-01-16 15:26:56 -02:00
Roberto Ierusalimschy
438a9fcc78 LUAI_MAXSHORTLEN moved from 'luaconf.h' to 'llimits.h' (does not
affect the API and is seldom modified)
2015-01-16 15:15:52 -02:00
Roberto Ierusalimschy
7e2015a46d size of short strings stored in a single byte, to reduce the size
of struct 'TString'
2015-01-16 14:54:37 -02:00
Roberto Ierusalimschy
5b01cb39b5 larger MINSTRTABSIZE (standard Lua starts with ~230 strings, after
oppening the standard libraries)
2015-01-16 13:41:03 -02:00
Roberto Ierusalimschy
a0503305bd comments 2015-01-16 11:26:55 -02:00
Roberto Ierusalimschy
965f74525b removed macro LUAI_FIRSTPSEUDOIDX (that stuff does not need
to be configurable)
2015-01-13 17:50:30 -02:00
Roberto Ierusalimschy
3f2e21f0ea Long double needs a larger LUAL_BUFFERSIZE (because
'string.format("%.99f", 1e4900)' can generate quite long strings),
but otherwise buffer can be 1~2K
2015-01-13 15:24:22 -02:00
Roberto Ierusalimschy
3509914916 BUG (when compiled with long double): buffer overflow when formatting
string.format("%.99f", 1e4930)
2015-01-13 15:18:25 -02:00
Roberto Ierusalimschy
ae27be40c9 better check for overflows in 'table.move' (removes restriction that
initial position should be positive)
2015-01-13 14:27:29 -02:00
Roberto Ierusalimschy
cdd26700e8 definition for 'MAXUPVAL' moved for a more "private" place and its
value and comment corrected to reflect current implementation
2015-01-13 13:49:11 -02:00
Roberto Ierusalimschy
a9a4bf68b0 typo in comment 2015-01-13 11:18:04 -02:00
Roberto Ierusalimschy
f31cc8e342 typo in error message 2015-01-12 17:32:32 -02:00
39 changed files with 1245 additions and 595 deletions

223
bugs
View File

@@ -1878,13 +1878,6 @@ for i=1,25 do print(i); crash(i) end
patch = [[
--- lundump.c 2008/04/04 16:00:45 2.7.1.3
+++ lundump.c 2008/04/04 19:51:41 2.7.1.4
@@ -1,5 +1,5 @@
/*
-** $Id: bugs,v 1.132 2014/05/07 16:57:27 roberto Exp roberto $
+** $Id: bugs,v 1.132 2014/05/07 16:57:27 roberto Exp roberto $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -161,7 +161,9 @@
static Proto* LoadFunction(LoadState* S, TString* p)
@@ -3220,6 +3213,26 @@ example = [[
(segfaults on some platforms with some compiler options)
]],
patch = [[
--- ltablib.c 2013/04/12 18:48:47 1.65.1.1
+++ ltablib.c 2014/05/07 16:32:55 1.65.1.2
@@ -134,13 +135,14 @@
static int unpack (lua_State *L) {
- int i, e, n;
+ int i, e;
+ unsigned int n;
luaL_checktype(L, 1, LUA_TTABLE);
i = luaL_optint(L, 2, 1);
e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1));
if (i > e) return 0; /* empty range */
- n = e - i + 1; /* number of elements */
- if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
+ n = (unsigned int)e - (unsigned int)i; /* number of elements minus 1 */
+ if (n > (INT_MAX - 10) || !lua_checkstack(L, ++n))
return luaL_error(L, "too many results to unpack");
lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
while (i++ < e) /* push arg[i + 1...e] */
]]
}
@@ -3248,6 +3261,200 @@ patch = [[
]]
}
Bug{
what = [[Chunk with too many lines can seg. fault]],
report = [[Roberto, 2014/11/14]],
since = [[5.1 (at least)]],
fix = nil,
example = [[
-- the cause of the bug is the use of an unitialized variable, so
-- it cannot be reproduced reliably
local s = string.rep("\n", 2^24)
print(load(function () return s end))
]],
patch = [[
--- llex.c 2013/08/30 15:49:41 2.63.1.2
+++ llex.c 2015/02/09 17:05:31
@@ -153,5 +153,5 @@
next(ls); /* skip `\n\r' or `\r\n' */
if (++ls->linenumber >= MAX_INT)
- luaX_syntaxerror(ls, "chunk has too many lines");
+ lexerror(ls, "chunk has too many lines", 0);
}
]]
}
-----------------------------------------------------------------
-- Lua 5.3.0
Bug{
what = [['string.format("%f")' can cause a buffer overflow
(only when 'lua_Number' is long double!)]],
report = [[Roberto, 2015/01/13]],
since = [[5.3]],
fix = nil,
example = [[string.format("%.99f", 1e4000) -- when floats are long double]],
patch = [[
--- lstrlib.c 2014/12/11 14:03:07 1.221
+++ lstrlib.c 2015/02/23 19:01:42
@@ -800,3 +800,4 @@
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
-#define MAX_ITEM 512
+#define MAX_ITEM \
+ (sizeof(lua_Number) <= 4 ? 150 : sizeof(lua_Number) <= 8 ? 450 : 5050)
]]
}
Bug{
what = [['debug.getlocal' on a coroutine suspended in a hook
can crash the interpreter]],
report = [[云风, 2015/02/11]],
since = [[5.2]],
fix = nil,
example = [[see http://lua-users.org/lists/lua-l/2015-02/msg00146.html]],
patch = [[
--- ldebug.c 2015/01/02 12:52:22 2.110
+++ ldebug.c 2015/02/13 16:03:23
@@ -49,4 +49,14 @@
+static void swapextra (lua_State *L) {
+ if (L->status == LUA_YIELD) {
+ CallInfo *ci = L->ci; /* get function that yielded */
+ StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
+ ci->func = restorestack(L, ci->extra);
+ ci->extra = savestack(L, temp);
+ }
+}
+
+
/*
** this function can be called asynchronous (e.g. during a signal)
@@ -145,4 +155,5 @@
const char *name;
lua_lock(L);
+ swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
@@ -159,4 +170,5 @@
}
}
+ swapextra(L);
lua_unlock(L);
return name;
@@ -166,10 +178,13 @@
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
StkId pos = 0; /* to avoid warnings */
- const char *name = findlocal(L, ar->i_ci, n, &pos);
+ const char *name;
lua_lock(L);
+ swapextra(L);
+ name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
}
+ swapextra(L);
lua_unlock(L);
return name;
@@ -271,4 +286,5 @@
StkId func;
lua_lock(L);
+ swapextra(L);
if (*what == '>') {
ci = NULL;
@@ -289,4 +305,5 @@
api_incr_top(L);
}
+ swapextra(L);
if (strchr(what, 'L'))
collectvalidlines(L, cl);
]]
}
Bug{
what = [[suspended '__le' metamethod can give wrong result]],
report = [[Eric Zhong, 2015/04/07]],
since = [[5.2]],
fix = nil,
example = [[
mt = {__le = function (a,b) coroutine.yield("yield"); return a.x <= b.x end}
t1 = setmetatable({x=1}, mt)
t2 = {x=2}
co = coroutine.wrap(function (a,b) return t2 <= t1 end)
co()
print(co()) --> true (should be false)
]],
patch = [[
--- lstate.h 2014/10/30 18:53:28 2.119
+++ lstate.h 2015/04/13 15:58:40
@@ -94,6 +94,7 @@
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
#define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
+#define CIST_LEQ (1<<7) /* using __lt for __le */
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
--- lvm.c 2014/12/27 20:30:38 2.232
+++ lvm.c 2015/04/13 15:51:30
@@ -292,9 +292,14 @@
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
return res;
- else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try 'lt' */
- luaG_ordererror(L, l, r);
- return !res;
+ else { /* try 'lt': */
+ L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
+ res = luaT_callorderTM(L, r, l, TM_LT);
+ L->ci->callstatus ^= CIST_LEQ; /* clear mark */
+ if (res < 0)
+ luaG_ordererror(L, l, r);
+ return !res; /* result is negated */
+ }
}
@@ -553,11 +558,11 @@
case OP_LE: case OP_LT: case OP_EQ: {
int res = !l_isfalse(L->top - 1);
L->top--;
- /* metamethod should not be called when operand is K */
- lua_assert(!ISK(GETARG_B(inst)));
- if (op == OP_LE && /* "<=" using "<" instead? */
- ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
- res = !res; /* invert result */
+ if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
+ lua_assert(op == OP_LE);
+ ci->callstatus ^= CIST_LEQ; /* clear mark */
+ res = !res; /* negate result */
+ }
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
if (res != GETARG_A(inst)) /* condition failed? */
ci->u.l.savedpc++; /* skip jump instruction */
]]
}
Bug{
what = [[return hook may not see correct values for
active local variables when function returns]],
report = [[Philipp Janda/Peng Yi, 2015/05/19]],
since = [[5.0]],
fix = nil,
example = [[
see messasge http://lua-users.org/lists/lua-l/2015-05/msg00376.html]],
patch = [[
]]
}
--[=[
Bug{
@@ -3260,3 +3467,5 @@ patch = [[
]]
}
]=]

123
lapi.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 2.243 2014/11/12 13:28:54 roberto Exp roberto $
** $Id: lapi.c,v 2.248 2015/03/28 19:14:47 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -51,29 +51,29 @@ const char lua_ident[] =
/* test for valid but not pseudo index */
#define isstackindex(i, o) (isvalid(o) && !ispseudo(i))
#define api_checkvalidindex(o) api_check(isvalid(o), "invalid index")
#define api_checkvalidindex(l,o) api_check(l, isvalid(o), "invalid index")
#define api_checkstackindex(i, o) \
api_check(isstackindex(i, o), "index not in the stack")
#define api_checkstackindex(l, i, o) \
api_check(l, isstackindex(i, o), "index not in the stack")
static TValue *index2addr (lua_State *L, int idx) {
CallInfo *ci = L->ci;
if (idx > 0) {
TValue *o = ci->func + idx;
api_check(idx <= ci->top - (ci->func + 1), "unacceptable index");
api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index");
if (o >= L->top) return NONVALIDVALUE;
else return o;
}
else if (!ispseudo(idx)) { /* negative index */
api_check(idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index");
return L->top + idx;
}
else if (idx == LUA_REGISTRYINDEX)
return &G(L)->l_registry;
else { /* upvalues */
idx = LUA_REGISTRYINDEX - idx;
api_check(idx <= MAXUPVAL + 1, "upvalue index too large");
api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large");
if (ttislcf(ci->func)) /* light C function? */
return NONVALIDVALUE; /* it has no upvalues */
else {
@@ -98,7 +98,7 @@ LUA_API int lua_checkstack (lua_State *L, int n) {
int res;
CallInfo *ci = L->ci;
lua_lock(L);
api_check(n >= 0, "negative 'n'");
api_check(L, n >= 0, "negative 'n'");
if (L->stack_last - L->top > n) /* stack large enough? */
res = 1; /* yes; check is OK */
else { /* no; need to grow stack */
@@ -120,11 +120,12 @@ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
if (from == to) return;
lua_lock(to);
api_checknelems(from, n);
api_check(G(from) == G(to), "moving among independent states");
api_check(to->ci->top - to->top >= n, "not enough elements to move");
api_check(from, G(from) == G(to), "moving among independent states");
api_check(from, to->ci->top - to->top >= n, "not enough elements to move");
from->top -= n;
for (i = 0; i < n; i++) {
setobj2s(to, to->top++, from->top + i);
setobj2s(to, to->top, from->top + i);
api_incr_top(to);
}
lua_unlock(to);
}
@@ -159,7 +160,7 @@ LUA_API const lua_Number *lua_version (lua_State *L) {
LUA_API int lua_absindex (lua_State *L, int idx) {
return (idx > 0 || ispseudo(idx))
? idx
: cast_int(L->top - L->ci->func + idx);
: cast_int(L->top - L->ci->func) + idx;
}
@@ -172,13 +173,13 @@ LUA_API void lua_settop (lua_State *L, int idx) {
StkId func = L->ci->func;
lua_lock(L);
if (idx >= 0) {
api_check(idx <= L->stack_last - (func + 1), "new top too large");
api_check(L, idx <= L->stack_last - (func + 1), "new top too large");
while (L->top < (func + 1) + idx)
setnilvalue(L->top++);
L->top = (func + 1) + idx;
}
else {
api_check(-(idx+1) <= (L->top - (func + 1)), "invalid new top");
api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top");
L->top += idx+1; /* 'subtract' index (index is negative) */
}
lua_unlock(L);
@@ -208,8 +209,8 @@ LUA_API void lua_rotate (lua_State *L, int idx, int n) {
lua_lock(L);
t = L->top - 1; /* end of stack segment being rotated */
p = index2addr(L, idx); /* start of segment */
api_checkstackindex(idx, p);
api_check((n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
api_checkstackindex(L, idx, p);
api_check(L, (n >= 0 ? n : -n) <= (t - p + 1), "invalid 'n'");
m = (n >= 0 ? t - n : p - n - 1); /* end of prefix */
reverse(L, p, m); /* reverse the prefix with length 'n' */
reverse(L, m + 1, t); /* reverse the suffix */
@@ -223,7 +224,7 @@ LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) {
lua_lock(L);
fr = index2addr(L, fromidx);
to = index2addr(L, toidx);
api_checkvalidindex(to);
api_checkvalidindex(L, to);
setobj(L, to, fr);
if (isupvalue(toidx)) /* function upvalue? */
luaC_barrier(L, clCvalue(L->ci->func), fr);
@@ -255,7 +256,7 @@ LUA_API int lua_type (lua_State *L, int idx) {
LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L);
api_check(LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
api_check(L, LUA_TNONE <= t && t < LUA_NUMTAGS, "invalid tag");
return ttypename(t);
}
@@ -305,7 +306,7 @@ LUA_API void lua_arith (lua_State *L, int op) {
else { /* for unary operations, add fake 2nd operand */
api_checknelems(L, 1);
setobjs2s(L, L->top, L->top - 1);
L->top++;
api_incr_top(L);
}
/* first operand at top - 2, second at top - 1; result go to top - 2 */
luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
@@ -325,7 +326,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
default: api_check(0, "invalid option");
default: api_check(L, 0, "invalid option");
}
}
lua_unlock(L);
@@ -382,15 +383,17 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
luaO_tostring(L, o);
lua_unlock(L);
}
if (len != NULL) *len = tsvalue(o)->len;
if (len != NULL)
*len = vslen(o);
return svalue(o);
}
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
switch (ttnov(o)) {
case LUA_TSTRING: return tsvalue(o)->len;
switch (ttype(o)) {
case LUA_TSHRSTR: return tsvalue(o)->shrlen;
case LUA_TLNGSTR: return tsvalue(o)->u.lnglen;
case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: return luaH_getn(hvalue(o));
default: return 0;
@@ -431,9 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
case LUA_TCCL: return clCvalue(o);
case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o)));
case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, idx);
case LUA_TUSERDATA: return getudatamem(uvalue(o));
case LUA_TLIGHTUSERDATA: return pvalue(o);
default: return NULL;
}
}
@@ -482,20 +484,19 @@ LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) {
LUA_API const char *lua_pushstring (lua_State *L, const char *s) {
if (s == NULL) {
lua_pushnil(L);
return NULL;
}
lua_lock(L);
if (s == NULL)
setnilvalue(L->top);
else {
TString *ts;
lua_lock(L);
luaC_checkGC(L);
ts = luaS_new(L, s);
setsvalue2s(L, L->top, ts);
api_incr_top(L);
lua_unlock(L);
return getstr(ts);
s = getstr(ts); /* internal copy's address */
}
api_incr_top(L);
lua_unlock(L);
return s;
}
@@ -531,7 +532,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
else {
CClosure *cl;
api_checknelems(L, n);
api_check(n <= MAXUPVAL, "upvalue index too large");
api_check(L, n <= MAXUPVAL, "upvalue index too large");
luaC_checkGC(L);
cl = luaF_newCclosure(L, n);
cl->f = fn;
@@ -583,7 +584,8 @@ LUA_API int lua_getglobal (lua_State *L, const char *name) {
const TValue *gt; /* global table */
lua_lock(L);
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
setsvalue2s(L, L->top++, luaS_new(L, name));
setsvalue2s(L, L->top, luaS_new(L, name));
api_incr_top(L);
luaV_gettable(L, gt, L->top - 1, L->top - 1);
lua_unlock(L);
return ttnov(L->top - 1);
@@ -628,7 +630,7 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2addr(L, idx);
api_check(ttistable(t), "table expected");
api_check(L, ttistable(t), "table expected");
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
lua_unlock(L);
return ttnov(L->top - 1);
@@ -639,7 +641,7 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
StkId t;
lua_lock(L);
t = index2addr(L, idx);
api_check(ttistable(t), "table expected");
api_check(L, ttistable(t), "table expected");
setobj2s(L, L->top, luaH_getint(hvalue(t), n));
api_incr_top(L);
lua_unlock(L);
@@ -652,7 +654,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
TValue k;
lua_lock(L);
t = index2addr(L, idx);
api_check(ttistable(t), "table expected");
api_check(L, ttistable(t), "table expected");
setpvalue(&k, cast(void *, p));
setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L);
@@ -705,7 +707,7 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
StkId o;
lua_lock(L);
o = index2addr(L, idx);
api_check(ttisfulluserdata(o), "full userdata expected");
api_check(L, ttisfulluserdata(o), "full userdata expected");
getuservalue(L, uvalue(o), L->top);
api_incr_top(L);
lua_unlock(L);
@@ -724,7 +726,8 @@ LUA_API void lua_setglobal (lua_State *L, const char *name) {
lua_lock(L);
api_checknelems(L, 1);
gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
setsvalue2s(L, L->top++, luaS_new(L, name));
setsvalue2s(L, L->top, luaS_new(L, name));
api_incr_top(L);
luaV_settable(L, gt, L->top - 1, L->top - 2);
L->top -= 2; /* pop value and key */
lua_unlock(L);
@@ -747,7 +750,8 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
lua_lock(L);
api_checknelems(L, 1);
t = index2addr(L, idx);
setsvalue2s(L, L->top++, luaS_new(L, k));
setsvalue2s(L, L->top, luaS_new(L, k));
api_incr_top(L);
luaV_settable(L, t, L->top - 1, L->top - 2);
L->top -= 2; /* pop value and key */
lua_unlock(L);
@@ -759,7 +763,8 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
lua_lock(L);
api_checknelems(L, 1);
t = index2addr(L, idx);
setivalue(L->top++, n);
setivalue(L->top, n);
api_incr_top(L);
luaV_settable(L, t, L->top - 1, L->top - 2);
L->top -= 2; /* pop value and key */
lua_unlock(L);
@@ -772,7 +777,7 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 2);
o = index2addr(L, idx);
api_check(ttistable(o), "table expected");
api_check(L, ttistable(o), "table expected");
t = hvalue(o);
setobj2t(L, luaH_set(L, t, L->top-2), L->top-1);
invalidateTMcache(t);
@@ -788,7 +793,7 @@ LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
api_check(ttistable(o), "table expected");
api_check(L, ttistable(o), "table expected");
t = hvalue(o);
luaH_setint(L, t, n, L->top - 1);
luaC_barrierback(L, t, L->top-1);
@@ -804,7 +809,7 @@ LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
api_check(ttistable(o), "table expected");
api_check(L, ttistable(o), "table expected");
t = hvalue(o);
setpvalue(&k, cast(void *, p));
setobj2t(L, luaH_set(L, t, &k), L->top - 1);
@@ -823,7 +828,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
if (ttisnil(L->top - 1))
mt = NULL;
else {
api_check(ttistable(L->top - 1), "table expected");
api_check(L, ttistable(L->top - 1), "table expected");
mt = hvalue(L->top - 1);
}
switch (ttnov(obj)) {
@@ -859,7 +864,7 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 1);
o = index2addr(L, idx);
api_check(ttisfulluserdata(o), "full userdata expected");
api_check(L, ttisfulluserdata(o), "full userdata expected");
setuservalue(L, uvalue(o), L->top - 1);
luaC_barrier(L, gcvalue(o), L->top - 1);
L->top--;
@@ -873,7 +878,7 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) {
#define checkresults(L,na,nr) \
api_check((nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \
"results from function overflow current stack size")
@@ -881,10 +886,10 @@ LUA_API void lua_callk (lua_State *L, int nargs, int nresults,
lua_KContext ctx, lua_KFunction k) {
StkId func;
lua_lock(L);
api_check(k == NULL || !isLua(L->ci),
api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
func = L->top - (nargs+1);
if (k != NULL && L->nny == 0) { /* need to prepare continuation? */
@@ -922,16 +927,16 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
int status;
ptrdiff_t func;
lua_lock(L);
api_check(k == NULL || !isLua(L->ci),
api_check(L, k == NULL || !isLua(L->ci),
"cannot use continuations inside hooks");
api_checknelems(L, nargs+1);
api_check(L->status == LUA_OK, "cannot do calls on non-normal thread");
api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread");
checkresults(L, nargs, nresults);
if (errfunc == 0)
func = 0;
else {
StkId o = index2addr(L, errfunc);
api_checkstackindex(errfunc, o);
api_checkstackindex(L, errfunc, o);
func = savestack(L, o);
}
c.func = L->top - (nargs+1); /* function to be called */
@@ -1096,7 +1101,7 @@ LUA_API int lua_next (lua_State *L, int idx) {
int more;
lua_lock(L);
t = index2addr(L, idx);
api_check(ttistable(t), "table expected");
api_check(L, ttistable(t), "table expected");
more = luaH_next(L, hvalue(t), L->top - 1);
if (more) {
api_incr_top(L);
@@ -1228,9 +1233,9 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
LClosure *f;
StkId fi = index2addr(L, fidx);
api_check(ttisLclosure(fi), "Lua function expected");
api_check(L, ttisLclosure(fi), "Lua function expected");
f = clLvalue(fi);
api_check((1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
if (pf) *pf = f;
return &f->upvals[n - 1]; /* get its upvalue pointer */
}
@@ -1244,11 +1249,11 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) {
}
case LUA_TCCL: { /* C closure */
CClosure *f = clCvalue(fi);
api_check(1 <= n && n <= f->nupvalues, "invalid upvalue index");
api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index");
return &f->upvalue[n - 1];
}
default: {
api_check(0, "closure expected");
api_check(L, 0, "closure expected");
return NULL;
}
}

6
lapi.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.h,v 2.7 2009/11/27 15:37:59 roberto Exp roberto $
** $Id: lapi.h,v 2.8 2014/07/15 21:26:50 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -11,13 +11,13 @@
#include "llimits.h"
#include "lstate.h"
#define api_incr_top(L) {L->top++; api_check(L->top <= L->ci->top, \
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
"stack overflow");}
#define adjustresults(L,nres) \
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
#define api_checknelems(L,n) api_check((n) < (L->top - L->ci->func), \
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
"not enough elements in the stack")

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.c,v 1.278 2014/12/13 17:47:58 roberto Exp roberto $
** $Id: lauxlib.c,v 1.279 2014/12/14 18:32:26 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -286,7 +286,7 @@ LUALIB_API int luaL_execresult (lua_State *L, int stat) {
*/
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
if (luaL_getmetatable(L, tname)) /* name already in use? */
if (luaL_getmetatable(L, tname) != LUA_TNIL) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
lua_newtable(L); /* create metatable */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbaselib.c,v 1.308 2014/12/08 15:26:55 roberto Exp roberto $
** $Id: lbaselib.c,v 1.309 2014/12/10 12:26:42 roberto Exp roberto $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -55,7 +55,7 @@ static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
return NULL;
do {
int digit = (isdigit((unsigned char)*s)) ? *s - '0'
: toupper((unsigned char)*s) - 'A' + 10;
: (toupper((unsigned char)*s) - 'A') + 10;
if (digit >= base) return NULL; /* invalid numeral */
n = n * base + digit;
s++;

17
lcode.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.98 2014/12/19 13:36:32 roberto Exp roberto $
** $Id: lcode.c,v 2.100 2015/03/28 19:14:47 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -29,8 +29,8 @@
#include "lvm.h"
/* Maximum number of registers in a Lua function */
#define MAXREGS 250
/* Maximum number of registers in a Lua function (must fit in 8 bits) */
#define MAXREGS 255
#define hasjumps(e) ((e)->t != (e)->f)
@@ -279,7 +279,8 @@ void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) {
if (newstack >= MAXREGS)
luaX_syntaxerror(fs->ls, "function or expression too complex");
luaX_syntaxerror(fs->ls,
"function or expression needs too many registers");
fs->f->maxstacksize = cast_byte(newstack);
}
}
@@ -573,8 +574,8 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
case VKFLT: {
e->u.info = luaK_numberK(fs, e->u.nval);
e->k = VK;
/* go through */
}
/* FALLTHROUGH */
case VK: {
vk:
if (e->u.info <= MAXINDEXRK) /* constant fits in 'argC'? */
@@ -793,7 +794,7 @@ static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
static void codeexpval (FuncState *fs, OpCode op,
expdesc *e1, expdesc *e2, int line) {
lua_assert(op >= OP_ADD);
if (op <= OP_BNOT && constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2))
if (op <= OP_BNOT && constfolding(fs, (op - OP_ADD) + LUA_OPADD, e1, e2))
return; /* result has been folded */
else {
int o1, o2;
@@ -920,11 +921,11 @@ void luaK_posfix (FuncState *fs, BinOpr op,
break;
}
case OPR_EQ: case OPR_LT: case OPR_LE: {
codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
codecomp(fs, cast(OpCode, (op - OPR_EQ) + OP_EQ), 1, e1, e2);
break;
}
case OPR_NE: case OPR_GT: case OPR_GE: {
codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
codecomp(fs, cast(OpCode, (op - OPR_NE) + OP_EQ), 0, e1, e2);
break;
}
default: lua_assert(0);

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldblib.c,v 1.147 2014/12/08 15:47:25 roberto Exp roberto $
** $Id: ldblib.c,v 1.148 2015/01/02 12:52:22 roberto Exp roberto $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -27,6 +27,17 @@
static const int HOOKKEY = 0;
/*
** If L1 != L, L1 can be in any state, and therefore there is no
** garanties about its stack space; any push in L1 must be
** checked.
*/
static void checkstack (lua_State *L, lua_State *L1, int n) {
if (L != L1 && !lua_checkstack(L1, n))
luaL_error(L, "stack overflow");
}
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
@@ -127,12 +138,16 @@ static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
/*
** Calls 'lua_getinfo' and collects all results in a new table.
** L1 needs stack space for an optional input (function) plus
** two optional outputs (function and line table) from function
** 'lua_getinfo'.
*/
static int db_getinfo (lua_State *L) {
lua_Debug ar;
int arg;
lua_State *L1 = getthread(L, &arg);
const char *options = luaL_optstring(L, arg+2, "flnStu");
checkstack(L, L1, 3);
if (lua_isfunction(L, arg + 1)) { /* info about a function? */
options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
@@ -190,6 +205,7 @@ static int db_getlocal (lua_State *L) {
int level = (int)luaL_checkinteger(L, arg + 1);
if (!lua_getstack(L1, level, &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
checkstack(L, L1, 1);
name = lua_getlocal(L1, &ar, nvar);
if (name) {
lua_xmove(L1, L, 1); /* move local value */
@@ -216,6 +232,7 @@ static int db_setlocal (lua_State *L) {
return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
checkstack(L, L1, 1);
lua_xmove(L, L1, 1);
name = lua_setlocal(L1, &ar, nvar);
if (name == NULL)
@@ -350,6 +367,7 @@ static int db_sethook (lua_State *L) {
lua_pushvalue(L, -1);
lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
}
checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
lua_pushvalue(L, arg + 1); /* value (hook function) */
lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
@@ -370,6 +388,7 @@ static int db_gethook (lua_State *L) {
lua_pushliteral(L, "external hook");
else { /* hook table must exist */
lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1);
lua_rawget(L, -2); /* 1st result = hooktable[L1] */
lua_remove(L, -2); /* remove hook table */

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 2.109 2014/12/10 11:30:09 roberto Exp roberto $
** $Id: ldebug.c,v 2.114 2015/03/28 19:14:47 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -34,6 +34,10 @@
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
/* Active Lua function (given call info) */
#define ci_func(ci) (clLvalue((ci)->func))
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
@@ -48,6 +52,22 @@ static int currentline (CallInfo *ci) {
}
/*
** If function yielded, its 'func' can be in the 'extra' field. The
** next function restores 'func' to its correct value for debugging
** purposes. (It exchanges 'func' and 'extra'; so, when called again,
** after debugging, it also "re-restores" ** 'func' to its altered value.
*/
static void swapextra (lua_State *L) {
if (L->status == LUA_YIELD) {
CallInfo *ci = L->ci; /* get function that yielded */
StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
ci->func = restorestack(L, ci->extra);
ci->extra = savestack(L, temp);
}
}
/*
** this function can be called asynchronous (e.g. during a signal)
*/
@@ -106,7 +126,7 @@ static const char *upvalname (Proto *p, int uv) {
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
if (n >= ci->u.l.base - ci->func - nparams)
if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
return NULL; /* no such vararg */
else {
*pos = ci->func + nparams + n;
@@ -144,6 +164,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
lua_lock(L);
swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL;
@@ -151,26 +172,30 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
}
else { /* active function; get information through 'ar' */
StkId pos = 0; /* to avoid warnings */
StkId pos = NULL; /* to avoid warnings */
name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobj2s(L, L->top, pos);
api_incr_top(L);
}
}
swapextra(L);
lua_unlock(L);
return name;
}
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
StkId pos = 0; /* to avoid warnings */
const char *name = findlocal(L, ar->i_ci, n, &pos);
StkId pos = NULL; /* to avoid warnings */
const char *name;
lua_lock(L);
swapextra(L);
name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
}
swapextra(L);
lua_unlock(L);
return name;
}
@@ -270,10 +295,11 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
CallInfo *ci;
StkId func;
lua_lock(L);
swapextra(L);
if (*what == '>') {
ci = NULL;
func = L->top - 1;
api_check(ttisfunction(func), "function expected");
api_check(L, ttisfunction(func), "function expected");
what++; /* skip the '>' */
L->top--; /* pop function */
}
@@ -288,6 +314,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
setobjs2s(L, L->top, func);
api_incr_top(L);
}
swapextra(L); /* correct before option 'L', which can raise a mem. error */
if (strchr(what, 'L'))
collectvalidlines(L, cl);
lua_unlock(L);
@@ -572,19 +599,16 @@ l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
}
static void addinfo (lua_State *L, const char *msg) {
CallInfo *ci = L->ci;
if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(ci);
TString *src = ci_func(ci)->p->source;
if (src)
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
else { /* no source available; use "?" instead */
buff[0] = '?'; buff[1] = '\0';
}
luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
/* add src:line information to 'msg' */
const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
int line) {
char buff[LUA_IDSIZE];
if (src)
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
else { /* no source available; use "?" instead */
buff[0] = '?'; buff[1] = '\0';
}
return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
}
@@ -601,10 +625,14 @@ l_noret luaG_errormsg (lua_State *L) {
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
CallInfo *ci = L->ci;
const char *msg;
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
va_end(argp);
if (isLua(ci)) /* if Lua function, add source:line information */
luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
luaG_errormsg(L);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldebug.h,v 2.11 2014/02/25 14:31:16 roberto Exp roberto $
** $Id: ldebug.h,v 2.13 2015/03/11 16:10:41 roberto Exp roberto $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@@ -17,9 +17,6 @@
#define resethookcount(L) (L->hookcount = L->basehookcount)
/* Active Lua function (given call info) */
#define ci_func(ci) (clLvalue((ci)->func))
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
@@ -33,6 +30,8 @@ LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
TString *src, int line);
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
LUAI_FUNC void luaG_traceexec (lua_State *L);

26
ldo.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.134 2014/11/10 17:42:04 roberto Exp roberto $
** $Id: ldo.c,v 2.137 2015/03/30 16:05:23 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -323,6 +323,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
case LUA_TCCL: { /* C closure */
f = clCvalue(func)->f;
Cfunc:
luaC_checkGC(L); /* stack grow uses memory */
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
@@ -330,20 +331,20 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*f)(L); /* do the actual call */
lua_lock(L);
api_checknelems(L, n);
luaD_poscall(L, L->top - n);
luaD_poscall(L, L->top - n, n);
return 1;
}
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
Proto *p = clLvalue(func)->p;
n = cast_int(L->top - func) - 1; /* number of real arguments */
luaC_checkGC(L); /* stack grow uses memory */
luaD_checkstack(L, p->maxstacksize);
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
@@ -364,7 +365,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
L->top = ci->top;
luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
@@ -379,7 +379,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
}
int luaD_poscall (lua_State *L, StkId firstResult) {
int luaD_poscall (lua_State *L, StkId firstResult, int nres) {
StkId res;
int wanted, i;
CallInfo *ci = L->ci;
@@ -393,9 +393,9 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
}
res = ci->func; /* res == final position of 1st result */
wanted = ci->nresults;
L->ci = ci = ci->previous; /* back to caller */
L->ci = ci->previous; /* back to caller */
/* move results to correct place */
for (i = wanted; i != 0 && firstResult < L->top; i--)
for (i = wanted; i != 0 && nres-- > 0; i--)
setobjs2s(L, res++, firstResult++);
while (i-- > 0)
setnilvalue(res++);
@@ -449,7 +449,7 @@ static void finishCcall (lua_State *L, int status) {
lua_lock(L);
api_checknelems(L, n);
/* finish 'luaD_precall' */
luaD_poscall(L, L->top - n);
luaD_poscall(L, L->top - n, n);
}
@@ -533,7 +533,8 @@ static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
*/
static void resume (lua_State *L, void *ud) {
int nCcalls = L->nCcalls;
StkId firstArg = cast(StkId, ud);
int n = *(cast(int*, ud)); /* number of arguments */
StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
if (nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
@@ -553,14 +554,13 @@ static void resume (lua_State *L, void *ud) {
luaV_execute(L); /* just continue running Lua code */
else { /* 'common' yield */
if (ci->u.c.k != NULL) { /* does it have a continuation function? */
int n;
lua_unlock(L);
n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
lua_lock(L);
api_checknelems(L, n);
firstArg = L->top - n; /* yield results come from continuation */
}
luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
luaD_poscall(L, firstArg, n); /* finish 'luaD_precall' */
}
unroll(L, NULL); /* run continuation */
}
@@ -576,7 +576,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, L->top - nargs);
status = luaD_rawrunprotected(L, resume, &nargs);
if (status == -1) /* error calling 'lua_resume'? */
status = LUA_ERRRUN;
else { /* continue running after recoverable errors */
@@ -619,7 +619,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
L->status = LUA_YIELD;
ci->extra = savestack(L, ci->func); /* save current 'func' */
if (isLua(ci)) { /* inside a hook? */
api_check(k == NULL, "hooks cannot continue after yielding");
api_check(L, k == NULL, "hooks cannot continue after yielding");
}
else {
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */

4
ldo.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.h,v 2.20 2011/11/29 15:55:08 roberto Exp roberto $
** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -34,7 +34,7 @@ LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
int allowyield);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult, int nres);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldump.c,v 2.33 2014/07/18 13:36:14 roberto Exp roberto $
** $Id: ldump.c,v 2.35 2015/01/16 16:54:37 roberto Exp roberto $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -74,14 +74,15 @@ static void DumpString (const TString *s, DumpState *D) {
if (s == NULL)
DumpByte(0, D);
else {
size_t size = s->len + 1; /* include trailing '\0' */
size_t size = tsslen(s) + 1; /* include trailing '\0' */
const char *str = getstr(s);
if (size < 0xFF)
DumpByte(cast_int(size), D);
else {
DumpByte(0xFF, D);
DumpVar(size, D);
}
DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */
DumpVector(str, size - 1, D); /* no need to save '\0' */
}
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lfunc.h,v 2.13 2014/02/18 13:39:37 roberto Exp roberto $
** $Id: lfunc.h,v 2.14 2014/06/19 18:27:20 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -22,6 +22,13 @@
#define isintwups(L) (L->twups != L)
/*
** maximum number of upvalues in a closure (both C and Lua). (Value
** must fit in a VM register.)
*/
#define MAXUPVAL 255
/*
** Upvalues for Lua closures
*/

46
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 2.200 2014/11/02 19:19:04 roberto Exp roberto $
** $Id: lgc.c,v 2.204 2015/03/04 13:51:55 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -83,8 +83,13 @@
#define markvalue(g,o) { checkconsistency(o); \
if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
#define markobject(g,t) \
{ if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); }
#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); }
/*
** mark an object that can be NULL (either because it is really optional,
** or it was stripped as debug info, or inside an uncompleted structure)
*/
#define markobjectN(g,t) { if (t) markobject(g,t); }
static void reallymarkobject (global_State *g, GCObject *o);
@@ -226,15 +231,19 @@ static void reallymarkobject (global_State *g, GCObject *o) {
reentry:
white2gray(o);
switch (o->tt) {
case LUA_TSHRSTR:
case LUA_TSHRSTR: {
gray2black(o);
g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
break;
}
case LUA_TLNGSTR: {
gray2black(o);
g->GCmemtrav += sizestring(gco2ts(o));
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
break;
}
case LUA_TUSERDATA: {
TValue uvalue;
markobject(g, gco2u(o)->metatable); /* mark its metatable */
markobjectN(g, gco2u(o)->metatable); /* mark its metatable */
gray2black(o);
g->GCmemtrav += sizeudata(gco2u(o));
getuservalue(g->mainthread, gco2u(o), &uvalue);
@@ -275,7 +284,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
static void markmt (global_State *g) {
int i;
for (i=0; i < LUA_NUMTAGS; i++)
markobject(g, g->mt[i]);
markobjectN(g, g->mt[i]);
}
@@ -437,7 +446,7 @@ static void traversestrongtable (global_State *g, Table *h) {
static lu_mem traversetable (global_State *g, Table *h) {
const char *weakkey, *weakvalue;
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
markobject(g, h->metatable);
markobjectN(g, h->metatable);
if (mode && ttisstring(mode) && /* is there a weak mode? */
((weakkey = strchr(svalue(mode), 'k')),
(weakvalue = strchr(svalue(mode), 'v')),
@@ -457,19 +466,24 @@ static lu_mem traversetable (global_State *g, Table *h) {
}
/*
** Traverse a prototype. (While a prototype is being build, its
** arrays can be larger than needed; the extra slots are filled with
** NULL, so the use of 'markobjectN')
*/
static int traverseproto (global_State *g, Proto *f) {
int i;
if (f->cache && iswhite(f->cache))
f->cache = NULL; /* allow cache to be collected */
markobject(g, f->source);
markobjectN(g, f->source);
for (i = 0; i < f->sizek; i++) /* mark literals */
markvalue(g, &f->k[i]);
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
markobject(g, f->upvalues[i].name);
markobjectN(g, f->upvalues[i].name);
for (i = 0; i < f->sizep; i++) /* mark nested protos */
markobject(g, f->p[i]);
markobjectN(g, f->p[i]);
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
markobject(g, f->locvars[i].varname);
markobjectN(g, f->locvars[i].varname);
return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
sizeof(Proto *) * f->sizep +
sizeof(TValue) * f->sizek +
@@ -494,7 +508,7 @@ static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
*/
static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
int i;
markobject(g, cl->p); /* mark its prototype */
markobjectN(g, cl->p); /* mark its prototype */
for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
UpVal *uv = cl->upvals[i];
if (uv != NULL) {
@@ -689,9 +703,10 @@ static void freeobj (lua_State *L, GCObject *o) {
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
case LUA_TSHRSTR:
luaS_remove(L, gco2ts(o)); /* remove it from hash table */
/* go through */
luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
break;
case LUA_TLNGSTR: {
luaM_freemem(L, o, sizestring(gco2ts(o)));
luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
break;
}
default: lua_assert(0);
@@ -1002,6 +1017,7 @@ static l_mem atomic (lua_State *L) {
/* clear values from resurrected weak tables */
clearvalues(g, g->weak, origweak);
clearvalues(g, g->allweak, origall);
luaS_clearcache(g);
g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
work += g->GCmemtrav; /* complete counting */
return work; /* estimate of memory marked by 'atomic' */

View File

@@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 2.141 2014/11/21 12:17:33 roberto Exp roberto $
** $Id: liolib.c,v 2.143 2015/03/06 19:09:08 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -410,12 +410,6 @@ static int readdigits (RN *rn, int hex) {
}
/* access to locale "radix character" (decimal point) */
#if !defined(l_getlocaledecpoint)
#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
/*
** Read a number: first reads a valid prefix of a numeral into a buffer.
** Then it calls 'lua_stringtonumber' to check whether the format is
@@ -425,9 +419,10 @@ static int read_number (lua_State *L, FILE *f) {
RN rn;
int count = 0;
int hex = 0;
char decp[2] = ".";
char decp[2];
rn.f = f; rn.n = 0;
decp[0] = l_getlocaledecpoint(); /* get decimal point from locale */
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
decp[1] = '\0';
l_lockfile(rn.f);
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
@@ -457,7 +452,7 @@ static int read_number (lua_State *L, FILE *f) {
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f); /* no-op when c == EOF */
lua_pushlstring(L, NULL, 0);
lua_pushliteral(L, "");
return (c != EOF);
}

28
llex.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.c,v 2.88 2014/11/02 19:19:04 roberto Exp roberto $
** $Id: llex.c,v 2.92 2015/04/03 18:41:57 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -16,6 +16,7 @@
#include "lua.h"
#include "lctype.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
@@ -68,7 +69,7 @@ static void save (LexState *ls, int c) {
void luaX_init (lua_State *L) {
int i;
TString *e = luaS_new(L, LUA_ENV); /* create env name */
TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */
luaC_fix(L, obj2gco(e)); /* never collect this name */
for (i=0; i<NUM_RESERVED; i++) {
TString *ts = luaS_new(L, luaX_tokens[i]);
@@ -106,9 +107,7 @@ static const char *txtToken (LexState *ls, int token) {
static l_noret lexerror (LexState *ls, const char *msg, int token) {
char buff[LUA_IDSIZE];
luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
if (token)
luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
luaD_throw(ls->L, LUA_ERRSYNTAX);
@@ -172,7 +171,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
ls->linenumber = 1;
ls->lastline = 1;
ls->source = source;
ls->envn = luaS_new(L, LUA_ENV); /* get env name */
ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
}
@@ -221,11 +220,6 @@ static void buffreplace (LexState *ls, char from, char to) {
}
#if !defined(l_getlocaledecpoint)
#define l_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
#define buff2num(b,o) (luaO_str2num(luaZ_buffer(b), o) != 0)
/*
@@ -234,7 +228,7 @@ static void buffreplace (LexState *ls, char from, char to) {
*/
static void trydecpoint (LexState *ls, TValue *o) {
char old = ls->decpoint;
ls->decpoint = l_getlocaledecpoint();
ls->decpoint = lua_getlocaledecpoint();
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
if (!buff2num(ls->buff, o)) {
/* format error with correct decimal point: no more options */
@@ -283,8 +277,9 @@ static int read_numeral (LexState *ls, SemInfo *seminfo) {
/*
** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
** -1 if sequence is malformed
** skip a sequence '[=*[' or ']=*]'; if sequence is wellformed, return
** its number of '='s; otherwise, return a negative number (-1 iff there
** are no '='s after initial bracket)
*/
static int skip_sep (LexState *ls) {
int count = 0;
@@ -501,8 +496,9 @@ static int llex (LexState *ls, SemInfo *seminfo) {
read_long_string(ls, seminfo, sep);
return TK_STRING;
}
else if (sep == -1) return '[';
else lexerror(ls, "invalid long string delimiter", TK_STRING);
else if (sep != -1) /* '[=...' missing second bracket */
lexerror(ls, "invalid long string delimiter", TK_STRING);
return '[';
}
case '=': {
next(ls);

107
llimits.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: llimits.h,v 1.124 2014/11/02 19:33:33 roberto Exp roberto $
** $Id: llimits.h,v 1.134 2015/03/06 19:49:50 roberto Exp roberto $
** Limits, basic types, and some other 'installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -52,11 +52,11 @@ typedef unsigned char lu_byte;
/*
** conversion of pointer to integer:
** conversion of pointer to unsigned integer:
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
#define point2int(p) ((unsigned int)((size_t)(p) & UINT_MAX))
#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX))
@@ -88,22 +88,20 @@ typedef LUAI_UACINT l_uacInt;
/*
** assertion for checking API calls
*/
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(e) assert(e)
#else
#define luai_apicheck(e) lua_assert(e)
#if !defined(luai_apicheck)
#define luai_apicheck(l,e) lua_assert(e)
#endif
#define api_check(e,msg) luai_apicheck((e) && msg)
#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
/* macro to avoid warnings about unused variables */
#if !defined(UNUSED)
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#define UNUSED(x) ((void)(x))
#endif
/* type casts (a macro highlights casts in the code) */
#define cast(t, exp) ((t)(exp))
#define cast_void(i) cast(void, (i))
@@ -149,11 +147,6 @@ typedef LUAI_UACINT l_uacInt;
#define LUAI_MAXCCALLS 200
#endif
/*
** maximum number of upvalues in a closure (both C and Lua). (Value
** must fit in an unsigned char.)
*/
#define MAXUPVAL UCHAR_MAX
/*
@@ -168,10 +161,33 @@ typedef unsigned long Instruction;
/*
** Maximum length for short strings, that is, strings that are
** internalized. (Cannot be smaller than reserved words or tags for
** metamethods, as these strings must be internalized;
** #("function") = 8, #("__newindex") = 10.)
*/
#if !defined(LUAI_MAXSHORTLEN)
#define LUAI_MAXSHORTLEN 40
#endif
/* minimum size for the string table (must be power of 2) */
/*
** Initial size for the string table (must be power of 2).
** The Lua core alone registers ~50 strings (reserved words +
** metaevent keys + a few others). Libraries would typically add
** a few dozens more.
*/
#if !defined(MINSTRTABSIZE)
#define MINSTRTABSIZE 64 /* minimum size for "predefined" strings */
#define MINSTRTABSIZE 128
#endif
/*
** Size of cache for strings in the API (better be a prime)
*/
#if !defined(STRCACHE_SIZE)
#define STRCACHE_SIZE 127
#endif
@@ -181,11 +197,19 @@ typedef unsigned long Instruction;
#endif
/*
** macros that are executed whenether program enters the Lua core
** ('lua_lock') and leaves the core ('lua_unlock')
*/
#if !defined(lua_lock)
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
/*
** macro executed during Lua functions at points where the
** function can yield.
*/
#if !defined(luai_threadyield)
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif
@@ -222,6 +246,53 @@ typedef unsigned long Instruction;
/*
** The luai_num* macros define the primitive operations over numbers.
*/
/* floor division (defined as 'floor(a/b)') */
#if !defined(luai_numidiv)
#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b)))
#endif
/* float division */
#if !defined(luai_numdiv)
#define luai_numdiv(L,a,b) ((a)/(b))
#endif
/*
** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when
** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of
** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b)
** ~= floor(a/b)'. That happens when the division has a non-integer
** negative result, which is equivalent to the test below.
*/
#if !defined(luai_nummod)
#define luai_nummod(L,a,b,m) \
{ (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
#endif
/* exponentiation */
#if !defined(luai_numpow)
#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
#endif
/* the others are quite standard operations */
#if !defined(luai_numadd)
#define luai_numadd(L,a,b) ((a)+(b))
#define luai_numsub(L,a,b) ((a)-(b))
#define luai_nummul(L,a,b) ((a)*(b))
#define luai_numunm(L,a) (-(a))
#define luai_numeq(a,b) ((a)==(b))
#define luai_numlt(a,b) ((a)<(b))
#define luai_numle(a,b) ((a)<=(b))
#define luai_numisnan(a) (!luai_numeq((a), (a)))
#endif
/*
** macro to control inclusion of some hard tests on stack reallocation
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmathlib.c,v 1.113 2014/11/07 11:31:58 roberto Exp roberto $
** $Id: lmathlib.c,v 1.114 2014/12/27 20:32:26 roberto Exp roberto $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -183,6 +183,9 @@ static int math_log (lua_State *L) {
res = l_mathop(log)(x);
else {
lua_Number base = luaL_checknumber(L, 2);
#if !defined(LUA_USE_C89)
if (base == 2.0) res = l_mathop(log2)(x); else
#endif
if (base == 10.0) res = l_mathop(log10)(x);
else res = l_mathop(log)(x)/l_mathop(log)(base);
}

11
lmem.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lmem.c,v 1.88 2014/11/02 19:19:04 roberto Exp roberto $
** $Id: lmem.c,v 1.90 2015/03/03 18:18:29 roberto Exp roberto $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
@@ -85,10 +85,11 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
#endif
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0) {
api_check( nsize > realosize,
"realloc cannot fail when shrinking a block");
luaC_fullgc(L, 1); /* try to free some memory... */
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
lua_assert(nsize > realosize); /* cannot fail when shrinking a block */
if (g->version) { /* is state fully built? */
luaC_fullgc(L, 1); /* try to free some memory... */
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
}
if (newblock == NULL)
luaD_throw(L, LUA_ERRMEM);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: loadlib.c,v 1.123 2014/11/12 13:31:51 roberto Exp roberto $
** $Id: loadlib.c,v 1.125 2015/01/13 13:18:04 roberto Exp roberto $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -14,6 +14,7 @@
#include "lprefix.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -136,8 +137,8 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
#include <dlfcn.h>
/*
** Macro to covert pointer to void* to pointer to function. This cast
** is undefined according to ISO C, but POSIX assumes that it must work.
** Macro to convert pointer-to-void* to pointer-to-function. This cast
** is undefined according to ISO C, but POSIX assumes that it works.
** (The '__extension__' in gnu compilers is only to avoid warnings.)
*/
#if defined(__GNUC__)

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.c,v 2.100 2014/11/21 12:15:57 roberto Exp roberto $
** $Id: lobject.c,v 2.103 2015/03/28 19:14:47 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -10,6 +10,8 @@
#include "lprefix.h"
#include <locale.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -39,8 +41,12 @@ LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
int luaO_int2fb (unsigned int x) {
int e = 0; /* exponent */
if (x < 8) return x;
while (x >= 0x10) {
x = (x+1) >> 1;
while (x >= (8 << 4)) { /* coarse steps */
x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
e += 4;
}
while (x >= (8 << 1)) { /* fine steps */
x = (x + 1) >> 1; /* x = ceil(x / 2) */
e++;
}
return ((e+1) << 3) | (cast_int(x) - 8);
@@ -55,8 +61,11 @@ int luaO_fb2int (int x) {
}
/*
** Computes ceil(log2(x))
*/
int luaO_ceillog2 (unsigned int x) {
static const lu_byte log_2[256] = {
static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
@@ -149,13 +158,13 @@ void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
}
/* could not perform raw operation; try metamethod */
lua_assert(L != NULL); /* should not fail when folding (compile time) */
luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
}
int luaO_hexavalue (int c) {
if (lisdigit(c)) return c - '0';
else return ltolower(c) - 'a' + 10;
else return (ltolower(c) - 'a') + 10;
}
@@ -172,9 +181,8 @@ static int isneg (const char **s) {
** Lua's implementation for 'lua_strx2number'
** ===================================================================
*/
#if !defined(lua_strx2number)
#include <math.h>
#if !defined(lua_strx2number)
/* maximum number of significant digits to read (to avoid overflows
even with single floats) */
@@ -185,21 +193,22 @@ static int isneg (const char **s) {
** C99 specification for 'strtod'
*/
static lua_Number lua_strx2number (const char *s, char **endptr) {
int dot = lua_getlocaledecpoint();
lua_Number r = 0.0; /* result (accumulator) */
int sigdig = 0; /* number of significant digits */
int nosigdig = 0; /* number of non-significant digits */
int e = 0; /* exponent correction */
int neg; /* 1 if number is negative */
int dot = 0; /* true after seen a dot */
int hasdot = 0; /* true after seen a dot */
*endptr = cast(char *, s); /* nothing is valid yet */
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
neg = isneg(&s); /* check signal */
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
return 0.0; /* invalid format (no '0x') */
for (s += 2; ; s++) { /* skip '0x' and read numeral */
if (*s == '.') {
if (dot) break; /* second dot? stop loop */
else dot = 1;
if (*s == dot) {
if (hasdot) break; /* second dot? stop loop */
else hasdot = 1;
}
else if (lisxdigit(cast_uchar(*s))) {
if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
@@ -207,7 +216,7 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
else e++; /* too many digits; ignore, but still count for exponent */
if (dot) e--; /* decimal digit? correct exponent */
if (hasdot) e--; /* decimal digit? correct exponent */
}
else break; /* neither a dot nor a digit */
}
@@ -244,7 +253,7 @@ static const char *l_str2d (const char *s, lua_Number *result) {
*result = lua_strx2number(s, &endptr);
else
*result = lua_str2number(s, &endptr);
if (endptr == s) return 0; /* nothing recognized */
if (endptr == s) return NULL; /* nothing recognized */
while (lisspace(cast_uchar(*endptr))) endptr++;
return (*endptr == '\0' ? endptr : NULL); /* OK if no trailing characters */
}
@@ -290,7 +299,7 @@ size_t luaO_str2num (const char *s, TValue *o) {
}
else
return 0; /* conversion failed */
return (e - s + 1); /* success; return string size */
return (e - s) + 1; /* success; return string size */
}
@@ -329,7 +338,7 @@ void luaO_tostring (lua_State *L, StkId obj) {
len = lua_number2str(buff, fltvalue(obj));
#if !defined(LUA_COMPAT_FLOATSTRING)
if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
buff[len++] = '.';
buff[len++] = lua_getlocaledecpoint();
buff[len++] = '0'; /* adds '.0' to result */
}
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 2.105 2014/12/19 13:36:32 roberto Exp roberto $
** $Id: lobject.h,v 2.110 2015/04/02 21:10:53 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -35,8 +35,6 @@
** bit 6: whether value is collectable
*/
#define VARBITS (3 << 4)
/*
** LUA_TFUNCTION variants:
@@ -190,9 +188,15 @@ typedef struct lua_TValue TValue;
#define setfltvalue(obj,x) \
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
#define chgfltvalue(obj,x) \
{ TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); }
#define setivalue(obj,x) \
{ TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
#define chgivalue(obj,x) \
{ TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
#define setfvalue(obj,x) \
@@ -303,9 +307,12 @@ typedef TValue *StkId; /* index to stack elements */
typedef struct TString {
CommonHeader;
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
lu_byte shrlen; /* length for short strings */
unsigned int hash;
size_t len; /* number of characters in string */
struct TString *hnext; /* linked list for hash table */
union {
size_t lnglen; /* length for long strings */
struct TString *hnext; /* linked list for hash table */
} u;
} TString;
@@ -329,6 +336,12 @@ typedef union UTString {
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(tsvalue(o))
/* get string length from 'TString *s' */
#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
/* get string length from 'TValue *o' */
#define vslen(o) tsslen(tsvalue(o))
/*
** Header for userdata; memory area follows the end of this structure
@@ -361,13 +374,13 @@ typedef union UUdata {
#define setuservalue(L,u,o) \
{ const TValue *io=(o); Udata *iu = (u); \
iu->user_ = io->value_; iu->ttuv_ = io->tt_; \
iu->user_ = io->value_; iu->ttuv_ = rttype(io); \
checkliveness(G(L),io); }
#define getuservalue(L,u,o) \
{ TValue *io=(o); const Udata *iu = (u); \
io->value_ = iu->user_; io->tt_ = iu->ttuv_; \
io->value_ = iu->user_; settt_(io, iu->ttuv_); \
checkliveness(G(L),io); }
@@ -376,7 +389,7 @@ typedef union UUdata {
*/
typedef struct Upvaldesc {
TString *name; /* upvalue name (for debug information) */
lu_byte instack; /* whether it is in stack */
lu_byte instack; /* whether it is in stack (register) */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc;
@@ -399,7 +412,7 @@ typedef struct Proto {
CommonHeader;
lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg;
lu_byte maxstacksize; /* maximum stack used by this function */
lu_byte maxstacksize; /* number of registers needed by this function */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of 'k' */
int sizecode;
@@ -409,12 +422,12 @@ typedef struct Proto {
int linedefined;
int lastlinedefined;
TValue *k; /* constants used by the function */
Instruction *code;
Instruction *code; /* opcodes */
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines (debug information) */
LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */
struct LClosure *cache; /* last created closure with this prototype */
struct LClosure *cache; /* last-created closure with this prototype */
TString *source; /* used for debug information */
GCObject *gclist;
} Proto;

View File

@@ -1,5 +1,5 @@
/*
** $Id: loslib.c,v 1.53 2014/12/10 15:42:42 roberto Exp roberto $
** $Id: loslib.c,v 1.56 2015/02/09 17:41:54 roberto Exp roberto $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -22,10 +22,12 @@
#include "lualib.h"
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
/*
** {==================================================================
** list of valid conversion specifiers for the 'strftime' function
** ===================================================================
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
#if defined(LUA_USE_C89)
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
@@ -37,8 +39,14 @@
#endif
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for time-related stuff
** ===================================================================
*/
#if !defined(l_time_t) /* { */
/*
@@ -51,15 +59,41 @@
#endif /* } */
#if !defined(lua_tmpnam) /* { */
#if !defined(l_gmtime) /* { */
/*
** By default, Lua uses tmpnam except when POSIX is available, where it
** uses mkstemp.
** By default, Lua uses gmtime/localtime, except when POSIX is available,
** where it uses gmtime_r/localtime_r
*/
#if defined(LUA_USE_POSIX) /* { */
#define l_gmtime(t,r) gmtime_r(t,r)
#define l_localtime(t,r) localtime_r(t,r)
#else /* }{ */
/* ISO C definitions */
#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
#endif /* } */
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for 'tmpnam':
** By default, Lua uses tmpnam except when POSIX is available, where
** it uses mkstemp.
** ===================================================================
*/
#if !defined(lua_tmpnam) /* { */
#if defined(LUA_USE_POSIX) /* { */
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
@@ -83,31 +117,10 @@
#endif /* } */
#endif /* } */
/* }================================================================== */
#if !defined(l_gmtime) /* { */
/*
** By default, Lua uses gmtime/localtime, except when POSIX is available,
** where it uses gmtime_r/localtime_r
*/
#if defined(LUA_USE_POSIX) /* { */
#define l_gmtime(t,r) gmtime_r(t,r)
#define l_localtime(t,r) localtime_r(t,r)
#else /* }{ */
/* ISO C definitions */
#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
#endif /* } */
#endif /* } */
static int os_execute (lua_State *L) {
const char *cmd = luaL_optstring(L, 1, NULL);
@@ -287,7 +300,7 @@ static int os_time (lua_State *L) {
t = mktime(&ts);
}
if (t != (time_t)(l_timet)t)
luaL_error(L, "time result cannot be represented in this Lua instalation");
luaL_error(L, "time result cannot be represented in this Lua installation");
else if (t == (time_t)(-1))
lua_pushnil(L);
else
@@ -297,8 +310,9 @@ static int os_time (lua_State *L) {
static int os_difftime (lua_State *L) {
double res = difftime((l_checktime(L, 1)), (l_checktime(L, 2)));
lua_pushnumber(L, (lua_Number)res);
time_t t1 = l_checktime(L, 1);
time_t t2 = l_checktime(L, 2);
lua_pushnumber(L, (lua_Number)difftime(t1, t2));
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 2.126 2014/11/02 19:19:04 roberto Exp roberto $
** $Id: lstate.c,v 2.127 2014/11/02 19:33:33 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -37,9 +37,6 @@
#endif
#define MEMERRMSG "not enough memory"
/*
** a macro to help the creation of a unique random seed when a state is
** created; the seed is used to randomize hashes.
@@ -200,12 +197,9 @@ static void f_luaopen (lua_State *L, void *ud) {
UNUSED(ud);
stack_init(L, L); /* init stack */
init_registry(L, g);
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaS_init(L);
luaT_init(L);
luaX_init(L);
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
g->gcrunning = 1; /* allow gc */
g->version = lua_version(NULL);
luai_userstateopen(L);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 2.118 2014/10/25 11:50:46 roberto Exp roberto $
** $Id: lstate.h,v 2.121 2015/04/10 17:56:25 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -94,6 +94,7 @@ typedef struct CallInfo {
#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
#define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
#define CIST_LEQ (1<<7) /* using __lt for __le */
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
@@ -140,6 +141,7 @@ typedef struct global_State {
TString *memerrmsg; /* memory-error message */
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *strcache[STRCACHE_SIZE][1]; /* cache for strings in API */
} global_State;

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.c,v 2.44 2014/07/21 16:02:10 roberto Exp roberto $
** $Id: lstring.c,v 2.48 2015/03/25 13:42:19 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -22,6 +22,8 @@
#include "lstring.h"
#define MEMERRMSG "not enough memory"
/*
** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
@@ -36,10 +38,10 @@
** equality for long strings
*/
int luaS_eqlngstr (TString *a, TString *b) {
size_t len = a->len;
size_t len = a->u.lnglen;
lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
return (a == b) || /* same instance or... */
((len == b->len) && /* equal length and ... */
((len == b->u.lnglen) && /* equal length and ... */
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
}
@@ -69,9 +71,9 @@ void luaS_resize (lua_State *L, int newsize) {
TString *p = tb->hash[i];
tb->hash[i] = NULL;
while (p) { /* for each node in the list */
TString *hnext = p->hnext; /* save next */
TString *hnext = p->u.hnext; /* save next */
unsigned int h = lmod(p->hash, newsize); /* new position */
p->hnext = tb->hash[h]; /* chain it */
p->u.hnext = tb->hash[h]; /* chain it */
tb->hash[h] = p;
p = hnext;
}
@@ -85,6 +87,34 @@ void luaS_resize (lua_State *L, int newsize) {
}
/*
** Clear API string cache. (Entries cannot be empty, so fill them with
** a non-collectable string.)
*/
void luaS_clearcache (global_State *g) {
int i;
for (i = 0; i < STRCACHE_SIZE; i++) {
if (iswhite(g->strcache[i][0])) /* will entry be collected? */
g->strcache[i][0] = g->memerrmsg; /* replace it with something fixed */
}
}
/*
** Initialize the string table and the string cache
*/
void luaS_init (lua_State *L) {
global_State *g = G(L);
int i;
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
for (i = 0; i < STRCACHE_SIZE; i++) /* fill cache with valid strings */
g->strcache[i][0] = g->memerrmsg;
}
/*
** creates a new string object
@@ -97,7 +127,6 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l,
totalsize = sizelstring(l);
o = luaC_newobj(L, tag, totalsize);
ts = gco2ts(o);
ts->len = l;
ts->hash = h;
ts->extra = 0;
memcpy(getaddrstr(ts), str, l * sizeof(char));
@@ -110,8 +139,8 @@ void luaS_remove (lua_State *L, TString *ts) {
stringtable *tb = &G(L)->strt;
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
while (*p != ts) /* find previous element */
p = &(*p)->hnext;
*p = (*p)->hnext; /* remove element from its list */
p = &(*p)->u.hnext;
*p = (*p)->u.hnext; /* remove element from its list */
tb->nuse--;
}
@@ -124,8 +153,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
global_State *g = G(L);
unsigned int h = luaS_hash(str, l, g->seed);
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
for (ts = *list; ts != NULL; ts = ts->hnext) {
if (l == ts->len &&
for (ts = *list; ts != NULL; ts = ts->u.hnext) {
if (l == ts->shrlen &&
(memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
/* found! */
if (isdead(g, ts)) /* dead (but not collected yet)? */
@@ -138,7 +167,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) {
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
}
ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
ts->hnext = *list;
ts->shrlen = cast_byte(l);
ts->u.hnext = *list;
*list = ts;
g->strt.nuse++;
return ts;
@@ -152,18 +182,32 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
if (l <= LUAI_MAXSHORTLEN) /* short string? */
return internshrstr(L, str, l);
else {
TString *ts;
if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
luaM_toobig(L);
return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
ts->u.lnglen = l;
return ts;
}
}
/*
** new zero-terminated string
** Create or reuse a zero-terminated string, first checking in the
** cache (using the string address as a key). The cache can contain
** only zero-terminated strings, so it is safe to use 'strcmp' to
** check hits.
*/
TString *luaS_new (lua_State *L, const char *str) {
return luaS_newlstr(L, str, strlen(str));
unsigned int i = point2uint(str) % STRCACHE_SIZE; /* hash */
TString **p = G(L)->strcache[i];
if (strcmp(str, getstr(p[0])) == 0) /* hit? */
return p[0]; /* that it is */
else { /* normal route */
TString *s = luaS_newlstr(L, str, strlen(str));
p[0] = s;
return s;
}
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp roberto $
** $Id: lstring.h,v 1.58 2015/03/04 13:31:21 roberto Exp roberto $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -13,7 +13,6 @@
#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
#define sizestring(s) sizelstring((s)->len)
#define sizeludata(l) (sizeof(union UUdata) + (l))
#define sizeudata(u) sizeludata((u)->len)
@@ -37,6 +36,8 @@
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC void luaS_clearcache (global_State *g);
LUAI_FUNC void luaS_init (lua_State *L);
LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);

124
lstrlib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.220 2014/12/11 13:40:40 roberto Exp roberto $
** $Id: lstrlib.c,v 1.228 2015/04/03 18:41:57 roberto Exp roberto $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -11,6 +11,7 @@
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
@@ -70,7 +71,7 @@ static int str_sub (lua_State *L) {
if (start < 1) start = 1;
if (end > (lua_Integer)l) end = l;
if (start <= end)
lua_pushlstring(L, s + start - 1, (size_t)(end - start + 1));
lua_pushlstring(L, s + start - 1, (size_t)(end - start) + 1);
else lua_pushliteral(L, "");
return 1;
}
@@ -149,9 +150,9 @@ static int str_byte (lua_State *L) {
if (posi < 1) posi = 1;
if (pose > (lua_Integer)l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
n = (int)(pose - posi + 1);
if (posi + n <= pose) /* arithmetic overflow? */
if (pose - posi >= INT_MAX) /* arithmetic overflow? */
return luaL_error(L, "string slice too long");
n = (int)(pose - posi) + 1;
luaL_checkstack(L, n, "string slice too long");
for (i=0; i<n; i++)
lua_pushinteger(L, uchar(s[posi+i-1]));
@@ -499,7 +500,7 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
}
case '+': /* 1 or more repetitions */
s++; /* 1 match already done */
/* go through */
/* FALLTHROUGH */
case '*': /* 0 or more repetitions */
s = max_expand(ms, s, p, ep);
break;
@@ -554,7 +555,7 @@ static void push_onecapture (MatchState *ms, int i, const char *s,
ptrdiff_t l = ms->capture[i].len;
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
if (l == CAP_POSITION)
lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
else
lua_pushlstring(ms->L, ms->capture[i].init, l);
}
@@ -598,8 +599,8 @@ static int str_find_aux (lua_State *L, int find) {
/* do a plain search */
const char *s2 = lmemfind(s + init - 1, ls - (size_t)init + 1, p, lp);
if (s2) {
lua_pushinteger(L, s2 - s + 1);
lua_pushinteger(L, s2 - s + lp);
lua_pushinteger(L, (s2 - s) + 1);
lua_pushinteger(L, (s2 - s) + lp);
return 2;
}
}
@@ -621,7 +622,7 @@ static int str_find_aux (lua_State *L, int find) {
lua_assert(ms.matchdepth == MAXCCALLS);
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
lua_pushinteger(L, s1 - s + 1); /* start */
lua_pushinteger(L, (s1 - s) + 1); /* start */
lua_pushinteger(L, res - s); /* end */
return push_captures(&ms, NULL, 0) + 2;
}
@@ -797,17 +798,100 @@ static int str_gsub (lua_State *L) {
** =======================================================
*/
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
#define MAX_ITEM 512
#if !defined(lua_number2strx) /* { */
/*
** Hexadecimal floating-point formatter
*/
#include <locale.h>
#include <math.h>
#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
/*
** Number of bits that goes into the first digit. It can be any value
** between 1 and 4; the following definition tries to align the number
** to nibble boundaries by making what is left after that first digit a
** multiple of 4.
*/
#define L_NBFD ((l_mathlim(MANT_DIG) - 1)%4 + 1)
/*
** Add integer part of 'x' to buffer and return new 'x'
*/
static lua_Number adddigit (char *buff, int n, lua_Number x) {
lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */
int d = (int)dd;
buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */
return x - dd; /* return what is left */
}
static int num2straux (char *buff, lua_Number x) {
if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */
return sprintf(buff, LUA_NUMBER_FMT, x); /* equal to '%g' */
else if (x == 0) { /* can be -0... */
sprintf(buff, LUA_NUMBER_FMT, x);
strcat(buff, "x0p+0"); /* reuses '0/-0' from 'sprintf'... */
return strlen(buff);
}
else {
int e;
lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */
int n = 0; /* character count */
if (m < 0) { /* is number negative? */
buff[n++] = '-'; /* add signal */
m = -m; /* make it positive */
}
buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */
m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
e -= L_NBFD; /* this digit goes before the radix point */
if (m > 0) { /* more digits? */
buff[n++] = lua_getlocaledecpoint(); /* add radix point */
do { /* add as many digits as needed */
m = adddigit(buff, n++, m * 16);
} while (m > 0);
}
n += sprintf(buff + n, "p%+d", e); /* add exponent */
return n;
}
}
static int lua_number2strx (lua_State *L, char *buff, const char *fmt,
lua_Number x) {
int n = num2straux(buff, x);
if (fmt[SIZELENMOD] == 'A') {
int i;
for (i = 0; i < n; i++)
buff[i] = toupper(uchar(buff[i]));
}
else if (fmt[SIZELENMOD] != 'a')
luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
return n;
}
#endif /* } */
/*
** Maximum size of each formatted item. This maximum size is produced
** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') +
** number of decimal digits to represent minfloat.
*/
#define MAX_ITEM (120 + l_mathlim(MAX_10_EXP))
/* valid flags in a format specification */
#define FLAGS "-+ #0"
/*
** maximum size of each format specification (such as "%-099.99d")
** (+2 for length modifiers; +10 accounts for %99.99x plus margin of error)
*/
#define MAX_FORMAT (sizeof(FLAGS) + 2 + 10)
#define MAX_FORMAT 32
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
@@ -849,8 +933,8 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
if (isdigit(uchar(*p)))
luaL_error(L, "invalid format (width or precision too long)");
*(form++) = '%';
memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
form += p - strfrmt + 1;
memcpy(form, strfrmt, ((p - strfrmt) + 1) * sizeof(char));
form += (p - strfrmt) + 1;
*form = '\0';
return p;
}
@@ -901,9 +985,10 @@ static int str_format (lua_State *L) {
nb = sprintf(buff, form, n);
break;
}
#if defined(LUA_USE_AFORMAT)
case 'a': case 'A':
#endif
addlenmod(form, LUA_NUMBER_FRMLEN);
nb = lua_number2strx(L, buff, form, luaL_checknumber(L, arg));
break;
case 'e': case 'E': case 'f':
case 'g': case 'G': {
addlenmod(form, LUA_NUMBER_FRMLEN);
@@ -921,13 +1006,12 @@ static int str_format (lua_State *L) {
/* no precision and string is too long to be formatted;
keep original string */
luaL_addvalue(&b);
break;
}
else {
nb = sprintf(buff, form, s);
lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
break;
}
break;
}
default: { /* also treat cases 'pnLlh' */
return luaL_error(L, "invalid option '%%%c' to 'format'",
@@ -1249,7 +1333,7 @@ static int str_pack (lua_State *L) {
totalsize += len + 1;
break;
}
case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* go through */
case Kpadding: luaL_addchar(&b, LUA_PACKPADBYTE); /* FALLTHROUGH */
case Kpaddalign: case Knop:
arg--; /* undo increment */
break;

123
ltable.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.c,v 2.99 2014/11/02 19:19:04 roberto Exp roberto $
** $Id: ltable.c,v 2.110 2015/05/20 16:22:30 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -14,8 +14,8 @@
** Implementation of tables (aka arrays, objects, or hash tables).
** Tables keep its elements in two parts: an array part and a hash part.
** Non-negative integer keys are all candidates to be kept in the array
** part. The actual size of the array is the largest 'n' such that at
** least half the slots between 0 and n are in use.
** part. The actual size of the array is the largest 'n' such that
** more than half the slots between 1 and n are in use.
** Hash uses a mix of chained scatter table with Brent's variation.
** A main invariant of these tables is that, if an element is not
** in its main position (i.e. the 'original' position that its hash gives
@@ -23,9 +23,7 @@
** Hence even when the load factor reaches 100%, performance remains good.
*/
#include <float.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include "lua.h"
@@ -71,7 +69,7 @@
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
#define hashpointer(t,p) hashmod(t, point2int(p))
#define hashpointer(t,p) hashmod(t, point2uint(p))
#define dummynode (&dummynode_)
@@ -85,31 +83,33 @@ static const Node dummynode_ = {
/*
** Checks whether a float has a value representable as a lua_Integer
** (and does the conversion if so)
** Hash for floating-point numbers.
** The main computation should be just
** n = frepx(n, &i); return (n * INT_MAX) + i
** but there are some numerical subtleties.
** In a two-complement representation, INT_MAX does not has an exact
** representation as a float, but INT_MIN does; because the absolute
** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
** INT_MIN.
*/
static int numisinteger (lua_Number x, lua_Integer *p) {
if ((x) == l_floor(x)) /* integral value? */
return lua_numbertointeger(x, p); /* try as an integer */
else return 0;
}
/*
** hash for floating-point numbers
*/
static Node *hashfloat (const Table *t, lua_Number n) {
#if !defined(l_hashfloat)
static int l_hashfloat (lua_Number n) {
int i;
n = l_mathop(frexp)(n, &i) * cast_num(INT_MAX - DBL_MAX_EXP);
i += cast_int(n);
if (i < 0) {
if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */
i = 0; /* handle INT_MIN */
i = -i; /* must be a positive value */
lua_Integer ni;
n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
if (!lua_numbertointeger(n, &ni)) { /* is 'n' inf/-inf/NaN? */
lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == HUGE_VAL);
return 0;
}
else { /* normal case */
unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni);
return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u);
}
return hashmod(t, i);
}
#endif
/*
@@ -121,13 +121,13 @@ static Node *mainposition (const Table *t, const TValue *key) {
case LUA_TNUMINT:
return hashint(t, ivalue(key));
case LUA_TNUMFLT:
return hashfloat(t, fltvalue(key));
return hashmod(t, l_hashfloat(fltvalue(key)));
case LUA_TSHRSTR:
return hashstr(t, tsvalue(key));
case LUA_TLNGSTR: {
TString *s = tsvalue(key);
if (s->extra == 0) { /* no hash? */
s->hash = luaS_hash(getstr(s), s->len, s->hash);
s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash);
s->extra = 1; /* now it has its hash */
}
return hashstr(t, tsvalue(key));
@@ -219,28 +219,29 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
/*
** Compute the optimal size for the array part of table 't'. 'nums' is a
** "count array" where 'nums[i]' is the number of integers in the table
** between 2^(i - 1) + 1 and 2^i. Put in '*narray' the optimal size, and
** return the number of elements that will go to that part.
** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
** integer keys in the table and leaves with the number of keys that
** will go to the array part; return the optimal size.
*/
static unsigned int computesizes (unsigned int nums[], unsigned int *narray) {
static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
int i;
unsigned int twotoi; /* 2^i */
unsigned int twotoi; /* 2^i (candidate for optimal size) */
unsigned int a = 0; /* number of elements smaller than 2^i */
unsigned int na = 0; /* number of elements to go to array part */
unsigned int n = 0; /* optimal size for array part */
for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
unsigned int optimal = 0; /* optimal size for array part */
/* loop while keys can fill more than half of total size */
for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) {
if (nums[i] > 0) {
a += nums[i];
if (a > twotoi/2) { /* more than half elements present? */
n = twotoi; /* optimal size (till now) */
na = a; /* all elements up to 'n' will go to array part */
optimal = twotoi; /* optimal size (till now) */
na = a; /* all elements up to 'optimal' will go to array part */
}
}
if (a == *narray) break; /* all elements already counted */
}
*narray = n;
lua_assert(*narray/2 <= na && na <= *narray);
return na;
lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
*pna = na;
return optimal;
}
@@ -255,6 +256,11 @@ static int countint (const TValue *key, unsigned int *nums) {
}
/*
** Count keys in array part of table 't': Fill 'nums[i]' with
** number of keys that will go into corresponding slice and return
** total number of non-nil keys.
*/
static unsigned int numusearray (const Table *t, unsigned int *nums) {
int lg;
unsigned int ttlg; /* 2^lg */
@@ -281,8 +287,7 @@ static unsigned int numusearray (const Table *t, unsigned int *nums) {
}
static int numusehash (const Table *t, unsigned int *nums,
unsigned int *pnasize) {
static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
int totaluse = 0; /* total number of elements */
int ause = 0; /* elements added to 'nums' (can go to array part) */
int i = sizenode(t);
@@ -293,7 +298,7 @@ static int numusehash (const Table *t, unsigned int *nums,
totaluse++;
}
}
*pnasize += ause;
*pna += ause;
return totaluse;
}
@@ -363,7 +368,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
}
}
if (!isdummy(nold))
luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */
}
@@ -376,21 +381,22 @@ void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
*/
static void rehash (lua_State *L, Table *t, const TValue *ek) {
unsigned int nasize, na;
unsigned int asize; /* optimal size for array part */
unsigned int na; /* number of keys in the array part */
unsigned int nums[MAXABITS + 1];
int i;
int totaluse;
for (i = 0; i <= MAXABITS; i++) nums[i] = 0; /* reset counts */
nasize = numusearray(t, nums); /* count keys in array part */
totaluse = nasize; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
na = numusearray(t, nums); /* count keys in array part */
totaluse = na; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &na); /* count keys in hash part */
/* count extra key */
nasize += countint(ek, nums);
na += countint(ek, nums);
totaluse++;
/* compute new size for array part */
na = computesizes(nums, &nasize);
asize = computesizes(nums, &na);
/* resize the table to new computed sizes */
luaH_resize(L, t, nasize, totaluse - na);
luaH_resize(L, t, asize, totaluse - na);
}
@@ -443,14 +449,13 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
TValue aux;
if (ttisnil(key)) luaG_runerror(L, "table index is nil");
else if (ttisfloat(key)) {
lua_Number n = fltvalue(key);
lua_Integer k;
if (luai_numisnan(n))
luaG_runerror(L, "table index is NaN");
if (numisinteger(n, &k)) { /* index is int? */
if (luaV_tointeger(key, &k, 0)) { /* index is int? */
setivalue(&aux, k);
key = &aux; /* insert it as an integer */
}
else if (luai_numisnan(fltvalue(key)))
luaG_runerror(L, "table index is NaN");
}
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
@@ -544,10 +549,10 @@ const TValue *luaH_get (Table *t, const TValue *key) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TNUMFLT: {
lua_Integer k;
if (numisinteger(fltvalue(key), &k)) /* index is int? */
if (luaV_tointeger(key, &k, 0)) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
/* else go through */
}
/* else... */
} /* FALLTHROUGH */
default: {
Node *n = mainposition(t, key);
for (;;) { /* check whether 'key' is somewhere in the chain */

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltablib.c,v 1.78 2014/10/25 11:50:46 roberto Exp roberto $
** $Id: ltablib.c,v 1.79 2014/11/02 19:19:04 roberto Exp roberto $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -124,8 +124,6 @@ static int tmove (lua_State *L) {
lua_Integer e = luaL_checkinteger(L, 3);
lua_Integer t = luaL_checkinteger(L, 4);
int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
/* the following restriction avoids several problems with overflows */
luaL_argcheck(L, f > 0, 2, "initial position must be positive");
if (e >= f) { /* otherwise, nothing to move */
lua_Integer n, i;
ta.geti = (luaL_getmetafield(L, 1, "__index") == LUA_TNIL)
@@ -134,7 +132,11 @@ static int tmove (lua_State *L) {
ta.seti = (luaL_getmetafield(L, tt, "__newindex") == LUA_TNIL)
? (luaL_checktype(L, tt, LUA_TTABLE), lua_rawseti)
: lua_seti;
luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
"too many elements to move");
n = e - f + 1; /* number of elements to move */
luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
"destination wrap around");
if (t > f) {
for (i = n - 1; i >= 0; i--) {
(*ta.geti)(L, 1, f + i);

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 2.200 2014/12/10 11:30:51 roberto Exp roberto $
** $Id: ltests.c,v 2.204 2015/03/13 16:24:50 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -289,11 +289,11 @@ static void checkLclosure (global_State *g, LClosure *cl) {
static int lua_checkpc (lua_State *L, CallInfo *ci) {
if (!isLua(ci)) return 1;
else {
Proto *p;
if (L->status != LUA_YIELD || ci != L->ci)
p = ci_func(ci)->p;
else /* real 'func' was saved in 'extra' field */
p = clLvalue(restorestack(L, ci->extra))->p;
/* if function yielded (inside a hook), real 'func' is in 'extra' field */
StkId f = (L->status != LUA_YIELD || ci != L->ci)
? ci->func
: restorestack(L, ci->extra);
Proto *p = clLvalue(f)->p;
return p->code <= ci->u.l.savedpc &&
ci->u.l.savedpc <= p->code + p->sizecode;
}
@@ -724,7 +724,7 @@ static int string_query (lua_State *L) {
else if (s < tb->size) {
TString *ts;
int n = 0;
for (ts = tb->hash[s]; ts != NULL; ts = ts->hnext) {
for (ts = tb->hash[s]; ts != NULL; ts = ts->u.hnext) {
setsvalue2s(L, L->top, ts);
api_incr_top(L);
n++;
@@ -916,6 +916,13 @@ static int int2fb_aux (lua_State *L) {
}
static int log2_aux (lua_State *L) {
unsigned int x = (unsigned int)luaL_checkinteger(L, 1);
lua_pushinteger(L, luaO_ceillog2(x));
return 1;
}
struct Aux { jmp_buf jb; const char *paniccode; lua_State *L; };
/*
@@ -1508,6 +1515,7 @@ static const struct luaL_Reg tests_funcs[] = {
{"getref", getref},
{"hash", hash_query},
{"int2fb", int2fb_aux},
{"log2", log2_aux},
{"limits", get_limits},
{"listcode", listcode},
{"listk", listk},

5
ltm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 2.32 2014/11/10 17:24:43 roberto Exp roberto $
** $Id: ltm.c,v 2.33 2014/11/21 12:15:57 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -117,6 +117,7 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
switch (event) {
case TM_CONCAT:
luaG_concaterror(L, p1, p2);
/* call never returns, but to avoid warnings: *//* FALLTHROUGH */
case TM_BAND: case TM_BOR: case TM_BXOR:
case TM_SHL: case TM_SHR: case TM_BNOT: {
lua_Number dummy;
@@ -124,8 +125,8 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
luaG_tointerror(L, p1, p2);
else
luaG_opinterror(L, p1, p2, "perform bitwise operation on");
/* else go through */
}
/* calls never return, but to avoid warnings: *//* FALLTHROUGH */
default:
luaG_opinterror(L, p1, p2, "perform arithmetic on");
}

36
lua.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.221 2014/11/02 19:33:33 roberto Exp roberto $
** $Id: lua.c,v 1.224 2015/03/10 14:15:06 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -80,9 +80,7 @@
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) \
if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_saveline(L,line) ((void)L, add_history(line))
#define lua_freeline(L,b) ((void)L, free(b))
#else /* }{ */
@@ -90,7 +88,7 @@
#define lua_readline(L,b,p) \
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_saveline(L,line) { (void)L; (void)line; }
#define lua_freeline(L,b) { (void)L; (void)b; }
#endif /* } */
@@ -315,11 +313,11 @@ static int pushline (lua_State *L, int firstline) {
lua_pop(L, 1); /* remove prompt */
l = strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[l-1] = '\0'; /* remove it */
b[--l] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
else
lua_pushstring(L, b);
lua_pushlstring(L, b, l);
lua_freeline(L, b);
return 1;
}
@@ -336,8 +334,12 @@ static int addreturn (lua_State *L) {
lua_pushvalue(L, -2); /* duplicate line */
lua_concat(L, 2); /* new line is "return ..." */
line = lua_tolstring(L, -1, &len);
if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK)
if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) {
lua_remove(L, -3); /* remove original line */
line += sizeof("return")/sizeof(char); /* remove 'return' for history */
if (line[0] != '\0') /* non empty? */
lua_saveline(L, line); /* keep history */
}
else
lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */
return status;
@@ -352,8 +354,10 @@ static int multiline (lua_State *L) {
size_t len;
const char *line = lua_tolstring(L, 1, &len); /* get what it has */
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
if (!incomplete(L, status) || !pushline(L, 0))
if (!incomplete(L, status) || !pushline(L, 0)) {
lua_saveline(L, line); /* keep history */
return status; /* cannot or should not try to add continuation line */
}
lua_pushliteral(L, "\n"); /* add newline... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
@@ -374,7 +378,6 @@ static int loadline (lua_State *L) {
return -1; /* no input */
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
status = multiline(L); /* try as command, maybe with continuation lines */
lua_saveline(L, 1); /* keep history */
lua_remove(L, 1); /* remove line from the stack */
lua_assert(lua_gettop(L) == 1);
return status;
@@ -482,14 +485,14 @@ static int collectargs (char **argv, int *first) {
args |= has_E;
break;
case 'i':
args |= has_i; /* goes through (-i implies -v) */
args |= has_i; /* (-i implies -v) *//* FALLTHROUGH */
case 'v':
if (argv[i][2] != '\0') /* extra characters after 1st? */
return has_error; /* invalid option */
args |= has_v;
break;
case 'e':
args |= has_e; /* go through */
args |= has_e; /* FALLTHROUGH */
case 'l': /* both options need an argument */
if (argv[i][2] == '\0') { /* no concatenated argument? */
i++; /* try next 'argv' */
@@ -513,17 +516,16 @@ static int collectargs (char **argv, int *first) {
static int runargs (lua_State *L, char **argv, int n) {
int i;
for (i = 1; i < n; i++) {
int status;
int option = argv[i][1];
lua_assert(argv[i][0] == '-'); /* already checked */
if (option == 'e' || option == 'l') {
int status;
const char *extra = argv[i] + 2; /* both options need an argument */
if (*extra == '\0') extra = argv[++i];
lua_assert(extra != NULL);
if (option == 'e')
status = dostring(L, extra, "=(command line)");
else
status = dolibrary(L, extra);
status = (option == 'e')
? dostring(L, extra, "=(command line)")
: dolibrary(L, extra);
if (status != LUA_OK) return 0;
}
}

13
lua.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.324 2014/12/08 15:12:07 roberto Exp roberto $
** $Id: lua.h,v 1.327 2015/03/10 14:17:51 roberto Exp roberto $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -19,7 +19,7 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "3"
#define LUA_VERSION_NUM 503
#define LUA_VERSION_RELEASE "0"
#define LUA_VERSION_RELEASE "1"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -35,9 +35,11 @@
/*
** pseudo-indices
** Pseudo-indices
** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
** space after that to help overflow detection)
*/
#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX
#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
@@ -356,8 +358,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
#define lua_pushliteral(L, s) \
lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
#define lua_pushglobaltable(L) \
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)

211
luaconf.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: luaconf.h,v 1.237 2014/12/26 14:44:44 roberto Exp roberto $
** $Id: luaconf.h,v 1.250 2015/04/03 18:41:57 roberto Exp roberto $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -96,10 +96,8 @@
/*
@@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines the type for
** Lua integers.
@@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines
** the type for Lua floats.
@@ LUA_INT_TYPE defines the type for Lua integers.
@@ LUA_FLOAT_TYPE defines the type for Lua floats.
** Lua should work fine with any mix of these options (if supported
** by your C compiler). The usual configurations are 64-bit integers
** and 'double' (the default), 32-bit integers and 'float' (for
@@ -107,31 +105,46 @@
** compliant with C99, which may not have support for 'long long').
*/
/* predefined options for LUA_INT_TYPE */
#define LUA_INT_INT 1
#define LUA_INT_LONG 2
#define LUA_INT_LONGLONG 3
/* predefined options for LUA_FLOAT_TYPE */
#define LUA_FLOAT_FLOAT 1
#define LUA_FLOAT_DOUBLE 2
#define LUA_FLOAT_LONGDOUBLE 3
#if defined(LUA_32BITS) /* { */
/*
** 32-bit integers and 'float'
*/
#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
#define LUA_INT_INT
#define LUA_INT_TYPE LUA_INT_INT
#else /* otherwise use 'long' */
#define LUA_INT_LONG
#define LUA_INT_TYPE LUA_INT_LONG
#endif
#define LUA_REAL_FLOAT
#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
#elif defined(LUA_C89_NUMBERS) /* }{ */
/*
** largest types available for C89 ('long' and 'double')
*/
#define LUA_INT_LONG
#define LUA_REAL_DOUBLE
#define LUA_INT_TYPE LUA_INT_LONG
#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
#endif /* } */
#else /* }{ */
/*
** default configuration for 64-bit Lua ('long long' and 'double')
*/
#define LUA_INT_LONGLONG
#define LUA_REAL_DOUBLE
#if !defined(LUA_INT_TYPE)
#define LUA_INT_TYPE LUA_INT_LONGLONG
#endif
#if !defined(LUA_FLOAT_TYPE)
#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
#endif /* } */
/* }================================================================== */
@@ -155,7 +168,7 @@
** non-conventional directories.
*/
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#if defined(_WIN32) /* { */
#if defined(_WIN32) /* { */
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
@@ -300,20 +313,15 @@
*/
#define LUA_COMPAT_APIINTCASTS
/*
@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
@@ a float mark ('.0').
** This macro is not on by default even in compatibility mode,
** because this is not really an incompatibility.
*/
/* #define LUA_COMPAT_FLOATSTRING */
#endif /* } */
#if defined(LUA_COMPAT_5_1) /* { */
/* Incompatibilities from 5.2 -> 5.3 */
#define LUA_COMPAT_MATHLIB
#define LUA_COMPAT_APIINTCASTS
/*
@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
** You can replace it with 'table.unpack'.
@@ -373,6 +381,15 @@
#endif /* } */
/*
@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
@@ a float mark ('.0').
** This macro is not on by default even in compatibility mode,
** because this is not really an incompatibility.
*/
/* #define LUA_COMPAT_FLOATSTRING */
/* }================================================================== */
@@ -380,30 +397,30 @@
/*
** {==================================================================
** Configuration for Numbers.
** Change these definitions if no predefined LUA_REAL_* / LUA_INT_*
** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
** satisfy your needs.
** ===================================================================
*/
/*
@@ LUA_NUMBER is the floating-point type used by Lua.
**
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@@ over a floating number.
**
@@ l_mathlim(x) corrects limit name 'x' to the proper float type
** by prefixing it with one of FLT/DBL/LDBL.
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
@@ LUA_NUMBER_FMT is the format for writing floats.
@@ lua_number2str converts a float to a string.
**
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
**
@@ lua_str2number converts a decimal numeric string to a number.
*/
#if defined(LUA_REAL_FLOAT) /* { single float */
#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
#define LUA_NUMBER float
#define l_mathlim(n) (FLT_##n)
#define LUAI_UACNUMBER double
#define LUA_NUMBER_FRMLEN ""
@@ -414,10 +431,12 @@
#define lua_str2number(s,p) strtof((s), (p))
#elif defined(LUA_REAL_LONGDOUBLE) /* }{ long double */
#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
#define LUA_NUMBER long double
#define l_mathlim(n) (LDBL_##n)
#define LUAI_UACNUMBER long double
#define LUA_NUMBER_FRMLEN "L"
@@ -427,10 +446,12 @@
#define lua_str2number(s,p) strtold((s), (p))
#elif defined(LUA_REAL_DOUBLE) /* }{ double */
#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
#define LUA_NUMBER double
#define l_mathlim(n) (DBL_##n)
#define LUAI_UACNUMBER double
#define LUA_NUMBER_FRMLEN ""
@@ -440,9 +461,9 @@
#define lua_str2number(s,p) strtod((s), (p))
#else /* }{ */
#else /* }{ */
#error "numeric real type not defined"
#error "numeric float type not defined"
#endif /* } */
@@ -466,46 +487,6 @@
(*(p) = (LUA_INTEGER)(n), 1))
/*
@@ The luai_num* macros define the primitive operations over numbers.
** They should work for any size of floating numbers.
*/
/* the following operations need the math library */
#if defined(lobject_c) || defined(lvm_c)
#include <math.h>
/* floor division (defined as 'floor(a/b)') */
#define luai_numidiv(L,a,b) ((void)L, l_mathop(floor)(luai_numdiv(L,a,b)))
/*
** module: defined as 'a - floor(a/b)*b'; the previous definition gives
** NaN when 'b' is huge, but the result should be 'a'. 'fmod' gives the
** result of 'a - trunc(a/b)*b', and therefore must be corrected when
** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a
** non-integer negative result, which is equivalent to the test below
*/
#define luai_nummod(L,a,b,m) \
{ (m) = l_mathop(fmod)(a,b); if ((m)*(b) < 0) (m) += (b); }
/* exponentiation */
#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
#endif
/* these are quite standard operations */
#if defined(LUA_CORE)
#define luai_numadd(L,a,b) ((a)+(b))
#define luai_numsub(L,a,b) ((a)-(b))
#define luai_nummul(L,a,b) ((a)*(b))
#define luai_numdiv(L,a,b) ((a)/(b))
#define luai_numunm(L,a) (-(a))
#define luai_numeq(a,b) ((a)==(b))
#define luai_numlt(a,b) ((a)<(b))
#define luai_numle(a,b) ((a)<=(b))
#define luai_numisnan(a) (!luai_numeq((a), (a)))
#endif
/*
@@ LUA_INTEGER is the integer type used by Lua.
@@ -538,7 +519,7 @@
/* now the variable definitions */
#if defined(LUA_INT_INT) /* { int */
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
#define LUA_INTEGER int
#define LUA_INTEGER_FRMLEN ""
@@ -546,7 +527,7 @@
#define LUA_MAXINTEGER INT_MAX
#define LUA_MININTEGER INT_MIN
#elif defined(LUA_INT_LONG) /* }{ long */
#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
#define LUA_INTEGER long
#define LUA_INTEGER_FRMLEN "l"
@@ -554,7 +535,7 @@
#define LUA_MAXINTEGER LONG_MAX
#define LUA_MININTEGER LONG_MIN
#elif defined(LUA_INT_LONGLONG) /* }{ long long */
#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
#if defined(LLONG_MAX) /* { */
/* use ISO C99 stuff */
@@ -592,13 +573,13 @@
/*
** {==================================================================
** Dependencies with C99
** Dependencies with C99 and other C details
** ===================================================================
*/
/*
@@ lua_strx2number converts an hexadecimal numeric string to a number.
** In C99, 'strtod' does both conversions. Otherwise, you can
** In C99, 'strtod' does that conversion. Otherwise, you can
** leave 'lua_strx2number' undefined and Lua will provide its own
** implementation.
*/
@@ -608,12 +589,13 @@
/*
@@ LUA_USE_AFORMAT allows '%a'/'%A' specifiers in 'string.format'
** Enable it if the C function 'printf' supports these specifiers.
** (C99 demands it and Windows also supports it.)
@@ lua_number2strx converts a float to an hexadecimal numeric string.
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
** provide its own implementation.
*/
#if !defined(LUA_USE_C89) || defined(LUA_USE_WINDOWS)
#define LUA_USE_AFORMAT
#if !defined(LUA_USE_C89)
#define lua_number2strx(L,b,f,n) sprintf(b,f,n)
#endif
@@ -642,12 +624,50 @@
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
__STDC_VERSION__ >= 199901L
#include <stdint.h>
#if defined (INTPTR_MAX) /* even in C99 this type is optional */
#if defined(INTPTR_MAX) /* even in C99 this type is optional */
#undef LUA_KCONTEXT
#define LUA_KCONTEXT intptr_t
#endif
#endif
/*
@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
** Change that if you do not want to use C locales. (Code using this
** macro must include header 'locale.h'.)
*/
#if !defined(lua_getlocaledecpoint)
#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
/* }================================================================== */
/*
** {==================================================================
** Language Variations
** =====================================================================
*/
/*
@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
** coercion from strings to numbers.
*/
/* #define LUA_NOCVTN2S */
/* #define LUA_NOCVTS2N */
/*
@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
** Define it as a help when debugging C code.
*/
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(l,e) assert(e)
#endif
/* }================================================================== */
@@ -671,9 +691,6 @@
#define LUAI_MAXSTACK 15000
#endif
/* reserve some space for error handling */
#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000)
/*
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
@@ -691,20 +708,18 @@
#define LUA_IDSIZE 60
/*
@@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is,
** strings that are internalized. (Cannot be smaller than reserved words
** or tags for metamethods, as these strings must be internalized;
** #("function") = 8, #("__newindex") = 10.)
*/
#define LUAI_MAXSHORTLEN 40
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
** CHANGE it if it uses too much C-stack space.
** CHANGE it if it uses too much C-stack space. (For long double,
** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
** smaller buffer would force a memory allocation for each call to
** 'string.format'.)
*/
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
#if defined(LUA_FLOAT_LONGDOUBLE)
#define LUAL_BUFFERSIZE 8192
#else
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
#endif
/* }================================================================== */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lutf8lib.c,v 1.12 2014/10/15 14:31:10 roberto Exp roberto $
** $Id: lutf8lib.c,v 1.14 2015/03/05 16:07:46 roberto Exp roberto $
** Standard library for UTF-8 manipulation
** See Copyright Notice in lua.h
*/
@@ -11,6 +11,7 @@
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
@@ -37,7 +38,7 @@ static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid.
*/
static const char *utf8_decode (const char *o, int *val) {
static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
const unsigned char *s = (const unsigned char *)o;
unsigned int c = s[0];
unsigned int res = 0; /* final result */
@@ -106,9 +107,9 @@ static int codepoint (lua_State *L) {
luaL_argcheck(L, posi >= 1, 2, "out of range");
luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
if (posi > pose) return 0; /* empty interval; return no values */
n = (int)(pose - posi + 1);
if (posi + n <= pose) /* (lua_Integer -> int) overflow? */
if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */
return luaL_error(L, "string slice too long");
n = (int)(pose - posi) + 1;
luaL_checkstack(L, n, "string slice too long");
n = 0;
se = s + pose;
@@ -234,7 +235,7 @@ static int iter_codes (lua_State *L) {
#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
static struct luaL_Reg funcs[] = {
static const luaL_Reg funcs[] = {
{"offset", byteoffset},
{"codepoint", codepoint},
{"char", utfchar},
@@ -248,7 +249,7 @@ static struct luaL_Reg funcs[] = {
LUAMOD_API int luaopen_utf8 (lua_State *L) {
luaL_newlib(L, funcs);
lua_pushliteral(L, UTF8PATT);
lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1);
lua_setfield(L, -2, "charpattern");
return 1;
}

256
lvm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 2.231 2014/12/19 13:36:32 roberto Exp roberto $
** $Id: lvm.c,v 2.244 2015/06/02 19:11:24 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -9,8 +9,9 @@
#include "lprefix.h"
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,36 +31,38 @@
#include "lvm.h"
/*
** You can define LUA_FLOORN2I if you want to convert floats to integers
** by flooring them (instead of raising an error if they are not
** integral values)
*/
#if !defined(LUA_FLOORN2I)
#define LUA_FLOORN2I 0
#endif
/* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 2000
/*
** Similar to 'tonumber', but does not attempt to convert strings and
** ensure correct precision (no extra bits). Used in comparisons.
** 'l_intfitsf' checks whether a given integer can be converted to a
** float without rounding. Used in comparisons. Left undefined if
** all integers fit in a float precisely.
*/
static int tofloat (const TValue *obj, lua_Number *n) {
if (ttisfloat(obj)) *n = fltvalue(obj);
else if (ttisinteger(obj)) {
volatile lua_Number x = cast_num(ivalue(obj)); /* avoid extra precision */
*n = x;
}
else {
*n = 0; /* to avoid warnings */
return 0;
}
return 1;
}
#if !defined(l_intfitsf)
/* number of bits in the mantissa of a float */
#define NBM (l_mathlim(MANT_DIG))
/*
** Check whether some integers may not fit in a float, that is, whether
** (maxinteger >> NBM) > 0 (that implies (1 << NBM) <= maxinteger).
** (The shifts are done in parts to avoid shifting by more than the size
** of an integer. In a worst case, NBM == 113 for long double and
** sizeof(integer) == 32.)
*/
#if ((((LUA_MAXINTEGER >> (NBM / 4)) >> (NBM / 4)) >> (NBM / 4)) \
>> (NBM - (3 * (NBM / 4)))) > 0
#define l_intfitsf(i) \
(-((lua_Integer)1 << NBM) <= (i) && (i) <= ((lua_Integer)1 << NBM))
#endif
#endif
/*
@@ -73,7 +76,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
return 1;
}
else if (cvt2num(obj) && /* string convertible to number? */
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
*n = nvalue(&v); /* convert result of 'luaO_str2num' to a float */
return 1;
}
@@ -88,7 +91,7 @@ int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
** mode == 1: takes the floor of the number
** mode == 2: takes the ceil of the number
*/
static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode) {
TValue v;
again:
if (ttisfloat(obj)) {
@@ -106,7 +109,7 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
return 1;
}
else if (cvt2num(obj) &&
luaO_str2num(svalue(obj), &v) == tsvalue(obj)->len + 1) {
luaO_str2num(svalue(obj), &v) == vslen(obj) + 1) {
obj = &v;
goto again; /* convert result from 'luaO_str2num' to an integer */
}
@@ -114,14 +117,6 @@ static int tointeger_aux (const TValue *obj, lua_Integer *p, int mode) {
}
/*
** try to convert a value to an integer
*/
int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
return tointeger_aux(obj, p, LUA_FLOORN2I);
}
/*
** Try to convert a 'for' limit to an integer, preserving the
** semantics of the loop.
@@ -140,11 +135,11 @@ int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
static int forlimit (const TValue *obj, lua_Integer *p, lua_Integer step,
int *stopnow) {
*stopnow = 0; /* usually, let loops run */
if (!tointeger_aux(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */
if (!luaV_tointeger(obj, p, (step < 0 ? 2 : 1))) { /* not fit in integer? */
lua_Number n; /* try to convert to float */
if (!tonumber(obj, &n)) /* cannot convert to float? */
return 0; /* not a number */
if (n > 0) { /* if true, float is larger than max integer */
if (luai_numlt(0, n)) { /* if true, float is larger than max integer */
*p = LUA_MAXINTEGER;
if (step < 0) *stopnow = 1;
}
@@ -239,9 +234,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
*/
static int l_strcmp (const TString *ls, const TString *rs) {
const char *l = getstr(ls);
size_t ll = ls->len;
size_t ll = tsslen(ls);
const char *r = getstr(rs);
size_t lr = rs->len;
size_t lr = tsslen(rs);
for (;;) { /* for each segment */
int temp = strcoll(l, r);
if (temp != 0) /* not equal? */
@@ -260,16 +255,103 @@ static int l_strcmp (const TString *ls, const TString *rs) {
}
/*
** Check whether integer 'i' is less than float 'f'. If 'i' has an
** exact representation as a float ('l_intfitsf'), compare numbers as
** floats. Otherwise, if 'f' is outside the range for integers, result
** is trivial. Otherwise, compare them as integers. (When 'i' has no
** float representation, either 'f' is "far away" from 'i' or 'f' has
** no precision left for a fractional part; either way, how 'f' is
** truncated is irrelevant.) When 'f' is NaN, comparisons must result
** in false.
*/
static int LTintfloat (lua_Integer i, lua_Number f) {
#if defined(l_intfitsf)
if (!l_intfitsf(i)) {
if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
return 1; /* f >= maxint + 1 > i */
else if (f > cast_num(LUA_MININTEGER)) /* minint < f <= maxint ? */
return (i < cast(lua_Integer, f)); /* compare them as integers */
else /* f <= minint <= i (or 'f' is NaN) --> not(i < f) */
return 0;
}
#endif
return luai_numlt(cast_num(i), f); /* compare them as floats */
}
/*
** Check whether integer 'i' is less than or equal to float 'f'.
** See comments on previous function.
*/
static int LEintfloat (lua_Integer i, lua_Number f) {
#if defined(l_intfitsf)
if (!l_intfitsf(i)) {
if (f >= -cast_num(LUA_MININTEGER)) /* -minint == maxint + 1 */
return 1; /* f >= maxint + 1 > i */
else if (f >= cast_num(LUA_MININTEGER)) /* minint <= f <= maxint ? */
return (i <= cast(lua_Integer, f)); /* compare them as integers */
else /* f < minint <= i (or 'f' is NaN) --> not(i <= f) */
return 0;
}
#endif
return luai_numle(cast_num(i), f); /* compare them as floats */
}
/*
** Return 'l < r', for numbers.
*/
static int LTnum (const TValue *l, const TValue *r) {
if (ttisinteger(l)) {
lua_Integer li = ivalue(l);
if (ttisinteger(r))
return li < ivalue(r); /* both are integers */
else /* 'l' is int and 'r' is float */
return LTintfloat(li, fltvalue(r)); /* l < r ? */
}
else {
lua_Number lf = fltvalue(l); /* 'l' must be float */
if (ttisfloat(r))
return luai_numlt(lf, fltvalue(r)); /* both are float */
else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
return 0; /* NaN < i is always false */
else /* without NaN, (l < r) <--> not(r <= l) */
return !LEintfloat(ivalue(r), lf); /* not (r <= l) ? */
}
}
/*
** Return 'l <= r', for numbers.
*/
static int LEnum (const TValue *l, const TValue *r) {
if (ttisinteger(l)) {
lua_Integer li = ivalue(l);
if (ttisinteger(r))
return li <= ivalue(r); /* both are integers */
else /* 'l' is int and 'r' is float */
return LEintfloat(li, fltvalue(r)); /* l <= r ? */
}
else {
lua_Number lf = fltvalue(l); /* 'l' must be float */
if (ttisfloat(r))
return luai_numle(lf, fltvalue(r)); /* both are float */
else if (luai_numisnan(lf)) /* 'r' is int and 'l' is float */
return 0; /* NaN <= i is always false */
else /* without NaN, (l <= r) <--> not(r < l) */
return !LTintfloat(ivalue(r), lf); /* not (r < l) ? */
}
}
/*
** Main operation less than; return 'l < r'.
*/
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int res;
lua_Number nl, nr;
if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */
return (ivalue(l) < ivalue(r));
else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
return luai_numlt(nl, nr);
if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
return LTnum(l, r);
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
return l_strcmp(tsvalue(l), tsvalue(r)) < 0;
else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) /* no metamethod? */
@@ -279,27 +361,34 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
/*
** Main operation less than or equal to; return 'l <= r'.
** Main operation less than or equal to; return 'l <= r'. If it needs
** a metamethod and there is no '__le', try '__lt', based on
** l <= r iff !(r < l) (assuming a total order). If the metamethod
** yields during this substitution, the continuation has to know
** about it (to negate the result of r<l); bit CIST_LEQ in the call
** status keeps that information.
*/
int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
lua_Number nl, nr;
if (ttisinteger(l) && ttisinteger(r)) /* both operands are integers? */
return (ivalue(l) <= ivalue(r));
else if (tofloat(l, &nl) && tofloat(r, &nr)) /* both are numbers? */
return luai_numle(nl, nr);
if (ttisnumber(l) && ttisnumber(r)) /* both operands are numbers? */
return LEnum(l, r);
else if (ttisstring(l) && ttisstring(r)) /* both are strings? */
return l_strcmp(tsvalue(l), tsvalue(r)) <= 0;
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try 'le' */
else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* try 'le' */
return res;
else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try 'lt' */
luaG_ordererror(L, l, r);
return !res;
else { /* try 'lt': */
L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
res = luaT_callorderTM(L, r, l, TM_LT);
L->ci->callstatus ^= CIST_LEQ; /* clear mark */
if (res < 0)
luaG_ordererror(L, l, r);
return !res; /* result is negated */
}
}
/*
** Main operation for equality of Lua values; return 't1 == t2'.
** Main operation for equality of Lua values; return 't1 == t2'.
** L == NULL means raw equality (no metamethods)
*/
int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
@@ -308,10 +397,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
return 0; /* only numbers can be equal with different variants */
else { /* two numbers with different variants */
lua_Number n1, n2; /* compare them as floats */
lua_assert(ttisnumber(t1) && ttisnumber(t2));
cast_void(tofloat(t1, &n1)); cast_void(tofloat(t2, &n2));
return luai_numeq(n1, n2);
lua_Integer i1, i2; /* compare them as integers */
return (tointeger(t1, &i1) && tointeger(t2, &i2) && i1 == i2);
}
}
/* values have same type and same variant */
@@ -354,6 +441,8 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
#define tostring(L,o) \
(ttisstring(o) || (cvt2str(o) && (luaO_tostring(L, o), 1)))
#define isemptystr(o) (ttisshrstring(o) && tsvalue(o)->shrlen == 0)
/*
** Main operation for concatenation: concat 'total' values in the stack,
** from 'L->top - total' up to 'L->top - 1'.
@@ -365,19 +454,19 @@ void luaV_concat (lua_State *L, int total) {
int n = 2; /* number of elements handled in this pass (at least 2) */
if (!(ttisstring(top-2) || cvt2str(top-2)) || !tostring(L, top-1))
luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
else if (isemptystr(top - 1)) /* second operand is empty? */
cast_void(tostring(L, top - 2)); /* result is first operand */
else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
else if (isemptystr(top - 2)) { /* first operand is an empty string? */
setobjs2s(L, top - 2, top - 1); /* result is second op. */
}
else {
/* at least two non-empty string values; get as many as possible */
size_t tl = tsvalue(top-1)->len;
size_t tl = vslen(top - 1);
char *buffer;
int i;
/* collect total length */
for (i = 1; i < total && tostring(L, top-i-1); i++) {
size_t l = tsvalue(top-i-1)->len;
size_t l = vslen(top - i - 1);
if (l >= (MAX_SIZE/sizeof(char)) - tl)
luaG_runerror(L, "string length overflow");
tl += l;
@@ -386,7 +475,7 @@ void luaV_concat (lua_State *L, int total) {
tl = 0;
n = i;
do { /* copy all strings to buffer */
size_t l = tsvalue(top-i)->len;
size_t l = vslen(top - i);
memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
tl += l;
} while (--i > 0);
@@ -403,7 +492,7 @@ void luaV_concat (lua_State *L, int total) {
*/
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
const TValue *tm;
switch (ttnov(rb)) {
switch (ttype(rb)) {
case LUA_TTABLE: {
Table *h = hvalue(rb);
tm = fasttm(L, h->metatable, TM_LEN);
@@ -411,8 +500,12 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
setivalue(ra, luaH_getn(h)); /* else primitive len */
return;
}
case LUA_TSTRING: {
setivalue(ra, tsvalue(rb)->len);
case LUA_TSHRSTR: {
setivalue(ra, tsvalue(rb)->shrlen);
return;
}
case LUA_TLNGSTR: {
setivalue(ra, tsvalue(rb)->u.lnglen);
return;
}
default: { /* try metamethod */
@@ -448,7 +541,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer m, lua_Integer n) {
/*
** Integer modulus; return 'm % n'. (Assume that C '%' with
** Integer modulus; return 'm % n'. (Assume that C '%' with
** negative operands follows C99 behavior. See previous comment
** about luaV_div.)
*/
@@ -553,11 +646,11 @@ void luaV_finishOp (lua_State *L) {
case OP_LE: case OP_LT: case OP_EQ: {
int res = !l_isfalse(L->top - 1);
L->top--;
/* metamethod should not be called when operand is K */
lua_assert(!ISK(GETARG_B(inst)));
if (op == OP_LE && /* "<=" using "<" instead? */
ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
res = !res; /* invert result */
if (ci->callstatus & CIST_LEQ) { /* "<=" using "<" instead? */
lua_assert(op == OP_LE);
ci->callstatus ^= CIST_LEQ; /* clear mark */
res = !res; /* negate result */
}
lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
if (res != GETARG_A(inst)) /* condition failed? */
ci->u.l.savedpc++; /* skip jump instruction */
@@ -607,7 +700,7 @@ void luaV_finishOp (lua_State *L) {
** some macros for common tasks in 'luaV_execute'
*/
#if !defined luai_runtimecheck
#if !defined(luai_runtimecheck)
#define luai_runtimecheck(L, c) /* void */
#endif
@@ -743,7 +836,7 @@ void luaV_execute (lua_State *L) {
Protect(luaV_gettable(L, rb, RKC(i), ra));
vmbreak;
}
vmcase(OP_ADD) {
vmcase(OP_ADD) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
lua_Number nb; lua_Number nc;
@@ -928,7 +1021,7 @@ void luaV_execute (lua_State *L) {
L->top = base + c + 1; /* mark the end of concat operands */
Protect(luaV_concat(L, c - b + 1));
ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */
rb = b + base;
rb = base + b;
setobjs2s(L, ra, rb);
checkGC(L, (ra >= rb ? ra + 1 : rb));
L->top = ci->top; /* restore top */
@@ -1031,9 +1124,8 @@ void luaV_execute (lua_State *L) {
}
vmcase(OP_RETURN) {
int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1;
if (cl->p->sizep > 0) luaF_close(L, base);
b = luaD_poscall(L, ra);
b = luaD_poscall(L, ra, (b != 0 ? b - 1 : L->top - ra));
if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
return; /* external invocation: return */
else { /* invocation via reentry: continue execution */
@@ -1051,7 +1143,7 @@ void luaV_execute (lua_State *L) {
lua_Integer limit = ivalue(ra + 1);
if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
setivalue(ra, idx); /* update internal index... */
chgivalue(ra, idx); /* update internal index... */
setivalue(ra + 3, idx); /* ...and external index */
}
}
@@ -1062,7 +1154,7 @@ void luaV_execute (lua_State *L) {
if (luai_numlt(0, step) ? luai_numle(idx, limit)
: luai_numle(limit, idx)) {
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
setfltvalue(ra, idx); /* update internal index... */
chgfltvalue(ra, idx); /* update internal index... */
setfltvalue(ra + 3, idx); /* ...and external index */
}
}

16
lvm.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.h,v 2.33 2014/07/30 14:42:44 roberto Exp roberto $
** $Id: lvm.h,v 2.34 2014/08/01 17:24:02 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -27,11 +27,21 @@
#endif
/*
** You can define LUA_FLOORN2I if you want to convert floats to integers
** by flooring them (instead of raising an error if they are not
** integral values)
*/
#if !defined(LUA_FLOORN2I)
#define LUA_FLOORN2I 0
#endif
#define tonumber(o,n) \
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
#define tointeger(o,i) \
(ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i))
(ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I))
#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
@@ -42,7 +52,7 @@ LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p);
LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,

View File

@@ -148,16 +148,16 @@ ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
ltm.h lzio.h lmem.h lundump.h
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
lgc.h lstate.h ltm.h lzio.h lmem.h
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldo.h \
lobject.h lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h \
ltable.h
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
lstring.h ltable.h
lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h
loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
@@ -170,25 +170,25 @@ lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
lstring.h ltable.h
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h llimits.h \
lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
ltests.o: ltests.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h lauxlib.h lcode.h llex.h lopcodes.h \
lparser.h lctype.h ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h \
lualib.h
ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h llimits.h \
lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
lundump.h
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
ltable.h lvm.h
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
lobject.h ltm.h lzio.h