Compare commits

...

26 Commits
v5.1 ... v5.1.1

Author SHA1 Message Date
Roberto Ierusalimschy
98194db429 details 2006-06-09 14:31:14 -03:00
Roberto Ierusalimschy
fad7582c9a explicit test for common error (due to compatibility issue) 2006-06-07 09:37:17 -03:00
Roberto Ierusalimschy
a62fca1ebb BUG: debug hooks may get wrong when mixed with coroutines 2006-06-05 16:36:45 -03:00
Roberto Ierusalimschy
2b5c1f99e5 small simplifications 2006-06-05 16:35:57 -03:00
Roberto Ierusalimschy
e2dc5f5d15 extra assertion 2006-06-05 12:58:59 -03:00
Roberto Ierusalimschy
ed64346b9d details 2006-06-05 12:57:59 -03:00
Roberto Ierusalimschy
475b0ecbf1 new macro LUA_RELEASE 2006-06-02 12:34:00 -03:00
Roberto Ierusalimschy
414359b2f1 new version number 2006-05-31 13:50:40 -03:00
Roberto Ierusalimschy
0079efc479 bug: collector did not compensate enough for userdata with finalizers 2006-05-24 11:34:06 -03:00
Roberto Ierusalimschy
ad0765b4f0 subtle problem with the garbage collector 2006-05-24 11:33:49 -03:00
Roberto Ierusalimschy
20f4bbdc3a does not accept garbage after options (e.g., -ixxx) 2006-05-24 11:16:39 -03:00
Roberto Ierusalimschy
c408158047 only destroy state after running all finalizers 2006-05-24 11:15:50 -03:00
Roberto Ierusalimschy
55e323190e files should not be operated after fclose, even when fclose fails 2006-05-08 17:14:16 -03:00
Roberto Ierusalimschy
fe8f4c06f1 detail (better error message for invalid format) 2006-04-26 17:41:19 -03:00
Roberto Ierusalimschy
c351392940 details 2006-04-26 15:19:49 -03:00
Roberto Ierusalimschy
18330b6091 lua_dostring/lua_dofile should return any values returned by the chunk 2006-04-12 17:31:15 -03:00
Roberto Ierusalimschy
8487913697 BUG: option '%q' for string.format does not handle '\r' correctly 2006-04-12 17:13:52 -03:00
Roberto Ierusalimschy
672bb67ee6 environment variable names should be configurable 2006-04-10 15:27:23 -03:00
Roberto Ierusalimschy
90df6b7a54 detail 2006-03-23 15:23:32 -03:00
Roberto Ierusalimschy
0238a0b01e BUG: luaL_checkudata may show wrong error message 2006-03-21 16:31:09 -03:00
Roberto Ierusalimschy
1ae0b6c0bf BUG: should copy the union, not (some of) its fields 2006-03-21 16:28:49 -03:00
Roberto Ierusalimschy
e1dda047b2 unused macro 2006-03-21 16:28:03 -03:00
Roberto Ierusalimschy
2c8206d448 bug in Lua 4.0.2: weak tables that survive one collection are never collected 2006-03-20 09:49:30 -03:00
Roberto Ierusalimschy
ae76307847 comment 2006-03-14 16:04:44 -03:00
Roberto Ierusalimschy
3d61c31e5a 'lparser.h' should not include 'ltable.h' 2006-03-09 15:15:48 -03:00
Roberto Ierusalimschy
44a9bd6a8c detail 2006-03-09 15:08:22 -03:00
26 changed files with 395 additions and 102 deletions

253
bugs
View File

@@ -1,4 +1,4 @@
--[[
--[=[
** lua.stx / llex.c
Tue Dec 2 10:45:48 EDT 1997
>> BUG: "lastline" was not reset on function entry, so debug information
@@ -336,7 +336,7 @@ Thu Mar 20 11:40:12 EST 2003
--]]
--]=]
-----------------------------------------------------------------
-- Lua 5.0 (final)
@@ -764,3 +764,252 @@ patch = [[
]],
}
Bug{
what = [[weak tables that survive one collection are never collected]],
report = [[Chromix, 02/01/2006]],
example = [[
a = {}
print(gcinfo())
for i = 1, 10000 do
a[i] = setmetatable({}, {__mode = "v"})
end
collectgarbage()
a = nil
collectgarbage()
print(gcinfo())
]],
patch = [[
* lgc.c
@@ -366,7 +366,7 @@
GCObject *curr;
int count = 0; /* number of collected items */
while ((curr = *p) != NULL) {
- if (curr->gch.marked > limit) {
+ if ((curr->gch.marked & ~(KEYWEAK | VALUEWEAK)) > limit) {
unmark(curr);
p = &curr->gch.next;
}
]],
}
-----------------------------------------------------------------
-- Lua 5.1
Bug{
what = [[In 16-bit machines, expressions and/or with numeric constants as the
right operand may result in weird values]],
report = [[Andreas Stenius/Kein-Hong Man, 15/03/2006]],
example = [[
print(false or 0) -- on 16-bit machines
]],
patch = [[
* lcode.c:
@@ -731,17 +731,15 @@
case OPR_AND: {
lua_assert(e1->t == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e1->f, e2->f);
- e1->k = e2->k; e1->u.s.info = e2->u.s.info;
- e1->u.s.aux = e2->u.s.aux; e1->t = e2->t;
+ luaK_concat(fs, &e2->f, e1->f);
+ *e1 = *e2;
break;
}
case OPR_OR: {
lua_assert(e1->f == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
- luaK_concat(fs, &e1->t, e2->t);
- e1->k = e2->k; e1->u.s.info = e2->u.s.info;
- e1->u.s.aux = e2->u.s.aux; e1->f = e2->f;
+ luaK_concat(fs, &e2->t, e1->t);
+ *e1 = *e2;
break;
}
]],
}
Bug{
what = [[luaL_checkudata may produce wrong error message]],
report = [[Greg Falcon, 21/03/2006]],
example = [[
getmetatable(io.stdin).__gc()
--> bad argument #1 to '__gc' (FILE* expected, got table)
]],
patch = [[
* lauxlib.c:
@@ -123,11 +123,17 @@
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
- lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
- if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2))
- luaL_typerror(L, ud, tname);
- lua_pop(L, 2); /* remove both metatables */
- return p;
+ if (p != NULL) { /* value is a userdata? */
+ if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
+ lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return p;
+ }
+ }
+ }
+ luaL_typerror(L, ud, tname); /* else error */
+ return NULL; /* to avoid warnings */
}
]]
}
Bug{
what = [[
In Windows,
when Lua is used in an application that also uses DirectX,
it may present an erractic behavior.
THIS IS NOT A LUA BUG!
The problem is that DirectX violates an ABI that Lua depends on.]],
patch = [[
The simplest solution is to use DirectX with
the D3DCREATE_FPU_PRESERVE flag.
Otherwise, you can change the definition of lua_number2int,
in luaconf.h, to this one:
#define lua_number2int(i,d) __asm fld d __asm fistp i
]],
}
Bug{
what = [[option '%q' in string.format does not handle '\r' correctly.]],
example = [[
local s = "a string with \r and \n and \r\n and \n\r"
local c = string.format("return %q", s)
assert(assert(loadstring(c))() == s)
]],
patch = [[
* lstrlib.c:
@@ -703,6 +703,10 @@
luaL_addchar(b, *s);
break;
}
+ case '\r': {
+ luaL_addlstring(b, "\\r", 2);
+ break;
+ }
case '\0': {
luaL_addlstring(b, "\\000", 4);
break;
]],
}
Bug{
what = [[lua_dostring/lua_dofile should return any values returned
by the chunk]],
patch = [[
* lauxlib.h:
@@ -108,9 +108,11 @@
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
-#define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, 0, 0))
+#define luaL_dofile(L, fn) \
+ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
-#define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, 0, 0))+#define luaL_dostring(L, s) \
+ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
]],
}
Bug{
what = [[garbage collector does not compensate enough for finalizers]],
patch = [[
lgc.c:
@@ -322,4 +322,6 @@
-static void propagateall (global_State *g) {
- while (g->gray) propagatemark(g);
+static size_t propagateall (global_State *g) {
+ size_t m = 0;
+ while (g->gray) m += propagatemark(g);
+ return m;
}
@@ -542,3 +544,3 @@
marktmu(g); /* mark `preserved' userdata */
- propagateall(g); /* remark, to propagate `preserveness' */
+ udsize += propagateall(g); /* remark, to propagate `preserveness' */
cleartable(g->weak); /* remove collected objects from weak tables */
@@ -592,2 +594,4 @@
GCTM(L);
+ if (g->estimate > GCFINALIZECOST)
+ g->estimate -= GCFINALIZECOST;
]]
}
But{
what = [[debug hooks may get wrong when mixed with coroutines]],
report = [[by Ivko Stanilov, 03/06/2006]],
example = [[
co = coroutine.create(function (a,b)
coroutine.yield(a, b)
return b, "end"
end)
debug.sethook(co, function() end, "lcr")
coroutine.resume(co, 100, 2000)
coroutine.resume(co, 100, 2000)
]],
patch = [[
* ldo.c:
@@ -389,6 +389,7 @@
return;
}
else { /* resuming from previous yield */
+ L->status = 0;
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@@ -399,7 +400,6 @@
else /* yielded inside a hook: just continue its execution */
L->base = L->ci->base;
}
- L->status = 0;
luaV_execute(L, cast_int(L->ci - L->base_ci));
}
]],
}

7
lapi.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 2.52 2005/12/22 16:19:56 roberto Exp roberto $
** $Id: lapi.c,v 2.54 2006/06/02 15:34:00 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -32,7 +32,7 @@
const char lua_ident[] =
"$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
"$Lua: " LUA_RELEASE " " LUA_COPYRIGHT " $\n"
"$Authors: " LUA_AUTHORS " $\n"
"$URL: www.lua.org $\n";
@@ -199,6 +199,9 @@ LUA_API void lua_insert (lua_State *L, int idx) {
LUA_API void lua_replace (lua_State *L, int idx) {
StkId o;
lua_lock(L);
/* explicit test for incompatible code */
if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci)
luaG_runerror(L, "no calling environment");
api_checknelems(L, 1);
o = index2adr(L, idx);
api_checkvalidindex(L, o);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.c,v 1.157 2005/12/29 15:32:11 roberto Exp roberto $
** $Id: lauxlib.c,v 1.158 2006/01/16 12:42:21 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -123,11 +123,17 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (p == NULL || !lua_getmetatable(L, ud) || !lua_rawequal(L, -1, -2))
luaL_typerror(L, ud, tname);
lua_pop(L, 2); /* remove both metatables */
return p;
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
}
luaL_typerror(L, ud, tname); /* else error */
return NULL; /* to avoid warnings */
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h,v 1.86 2005/10/21 13:47:42 roberto Exp roberto $
** $Id: lauxlib.h,v 1.87 2005/12/29 15:32:11 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -108,9 +108,11 @@ LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
#define luaL_dofile(L, fn) (luaL_loadfile(L, fn) || lua_pcall(L, 0, 0, 0))
#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, 0, 0))
#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbaselib.c,v 1.188 2005/12/29 15:32:11 roberto Exp roberto $
** $Id: lbaselib.c,v 1.190 2006/05/31 16:50:40 roberto Exp roberto $
** Basic library
** See Copyright Notice in lua.h
*/

14
lcode.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 2.23 2005/11/25 13:29:32 roberto Exp roberto $
** $Id: lcode.c,v 2.24 2005/12/22 16:19:56 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -731,17 +731,15 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
case OPR_AND: {
lua_assert(e1->t == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e1->f, e2->f);
e1->k = e2->k; e1->u.s.info = e2->u.s.info;
e1->u.s.aux = e2->u.s.aux; e1->t = e2->t;
luaK_concat(fs, &e2->f, e1->f);
*e1 = *e2;
break;
}
case OPR_OR: {
lua_assert(e1->f == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e1->t, e2->t);
e1->k = e2->k; e1->u.s.info = e2->u.s.info;
e1->u.s.aux = e2->u.s.aux; e1->f = e2->f;
luaK_concat(fs, &e2->t, e1->t);
*e1 = *e2;
break;
}
case OPR_CONCAT: {
@@ -750,7 +748,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
freeexp(fs, e1);
SETARG_B(getcode(fs, e2), e1->u.s.info);
e1->k = e2->k; e1->u.s.info = e2->u.s.info;
e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
}
else {
luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.h,v 1.46 2005/10/03 14:02:40 roberto Exp roberto $
** $Id: lcode.h,v 1.47 2005/11/08 19:44:31 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -32,7 +32,6 @@ typedef enum BinOpr {
OPR_NOBINOPR
} BinOpr;
#define binopistest(op) ((op) >= OPR_NE)
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;

7
ldo.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 2.36 2005/10/23 17:52:42 roberto Exp roberto $
** $Id: ldo.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -383,12 +383,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
if (L->status != LUA_YIELD) { /* start coroutine */
if (L->status == 0) { /* start coroutine? */
lua_assert(ci == L->base_ci && firstArg > L->base);
if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
return;
}
else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD);
L->status = 0;
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)->savedpc - 1)) == OP_CALL ||
@@ -399,7 +401,6 @@ static void resume (lua_State *L, void *ud) {
else /* yielded inside a hook: just continue its execution */
L->base = L->ci->base;
}
L->status = 0;
luaV_execute(L, cast_int(L->ci - L->base_ci));
}

12
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 2.36 2005/08/24 17:06:36 roberto Exp roberto $
** $Id: lgc.c,v 2.37 2005/12/22 16:19:56 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -320,8 +320,10 @@ static l_mem propagatemark (global_State *g) {
}
static void propagateall (global_State *g) {
while (g->gray) propagatemark(g);
static size_t propagateall (global_State *g) {
size_t m = 0;
while (g->gray) m += propagatemark(g);
return m;
}
@@ -540,7 +542,7 @@ static void atomic (lua_State *L) {
propagateall(g);
udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
marktmu(g); /* mark `preserved' userdata */
propagateall(g); /* remark, to propagate `preserveness' */
udsize += propagateall(g); /* remark, to propagate `preserveness' */
cleartable(g->weak); /* remove collected objects from weak tables */
/* flip current white */
g->currentwhite = cast_byte(otherwhite(g));
@@ -590,6 +592,8 @@ static l_mem singlestep (lua_State *L) {
case GCSfinalize: {
if (g->tmudata) {
GCTM(L);
if (g->estimate > GCFINALIZECOST)
g->estimate -= GCFINALIZECOST;
return GCFINALIZECOST;
}
else {

View File

@@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 2.71 2006/01/17 13:54:02 roberto Exp roberto $
** $Id: liolib.c,v 2.72 2006/01/28 12:59:13 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -99,7 +99,7 @@ static FILE **newfile (lua_State *L) {
static int io_pclose (lua_State *L) {
FILE **p = topfile(L);
int ok = lua_pclose(L, *p);
if (ok) *p = NULL;
*p = NULL;
return pushresult(L, ok, NULL);
}
@@ -107,7 +107,7 @@ static int io_pclose (lua_State *L) {
static int io_fclose (lua_State *L) {
FILE **p = topfile(L);
int ok = (fclose(*p) == 0);
if (ok) *p = NULL;
*p = NULL;
return pushresult(L, ok, NULL);
}

3
llex.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.c,v 2.18 2006/01/23 20:06:19 roberto Exp roberto $
** $Id: llex.c,v 2.19 2006/02/06 18:28:16 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -20,6 +20,7 @@
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "lzio.h"

6
llex.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.h,v 1.56 2005/12/07 15:33:27 roberto Exp roberto $
** $Id: llex.h,v 1.57 2005/12/07 15:43:05 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -68,9 +68,9 @@ typedef struct LexState {
LUAI_FUNC void luaX_init (lua_State *L);
LUAI_FUNC void luaX_setinput (lua_State *L, LexState *LS, ZIO *z,
LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
TString *source);
LUAI_FUNC TString *luaX_newstring (LexState *LS, const char *str, size_t l);
LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
LUAI_FUNC void luaX_next (LexState *ls);
LUAI_FUNC void luaX_lookahead (LexState *ls);
LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);

View File

@@ -1,5 +1,5 @@
/*
** $Id: loadlib.c,v 1.50 2005/12/19 20:56:39 roberto Exp roberto $
** $Id: loadlib.c,v 1.51 2005/12/29 15:32:11 roberto Exp roberto $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -22,10 +22,6 @@
#include "lualib.h"
/* environment variables that hold the search path for packages */
#define LUA_PATH "LUA_PATH"
#define LUA_CPATH "LUA_CPATH"
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"

View File

@@ -1,5 +1,5 @@
/*
** $Id: lopcodes.h,v 1.123 2005/10/23 17:37:55 roberto Exp roberto $
** $Id: lopcodes.h,v 1.124 2005/12/02 18:42:08 roberto Exp roberto $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -197,8 +197,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORLOOP,/* A C R(A+3), ... ,R(A+3+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then { pc++; R(A+2)=R(A+3); } */
OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: loslib.c,v 1.16 2005/12/22 16:19:56 roberto Exp roberto $
** $Id: loslib.c,v 1.18 2006/03/09 18:08:22 roberto Exp roberto $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -28,10 +28,7 @@ static int os_pushresult (lua_State *L, int i, const char *filename) {
}
else {
lua_pushnil(L);
if (filename)
lua_pushfstring(L, "%s: %s", filename, strerror(en));
else
lua_pushfstring(L, "%s", strerror(en));
lua_pushfstring(L, "%s: %s", filename, strerror(en));
lua_pushinteger(L, en);
return 3;
}
@@ -126,8 +123,7 @@ static int getfield (lua_State *L, const char *key, int d) {
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
time_t t = lua_isnoneornil(L, 2) ? time(NULL) :
(time_t)luaL_checknumber(L, 2);
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
struct tm *stm;
if (*s == '!') { /* UTC? */
stm = gmtime(&t);
@@ -199,9 +195,8 @@ static int os_setlocale (lua_State *L) {
LC_NUMERIC, LC_TIME};
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
const char *l = lua_tostring(L, 1);
const char *l = luaL_optstring(L, 1, NULL);
int op = luaL_checkoption(L, 2, "all", catnames);
luaL_argcheck(L, l || lua_isnoneornil(L, 1), 1, "string expected");
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 2.39 2005/12/07 15:43:05 roberto Exp roberto $
** $Id: lparser.c,v 2.41 2006/03/09 18:15:48 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -23,7 +23,7 @@
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
@@ -299,7 +299,8 @@ static void leaveblock (FuncState *fs) {
removevars(fs->ls, bl->nactvar);
if (bl->upval)
luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
lua_assert(!bl->isbreakable || !bl->upval); /* loops have no body */
/* a block either controls scope or breaks (never both) */
lua_assert(!bl->isbreakable || !bl->upval);
lua_assert(bl->nactvar == fs->nactvar);
fs->freereg = fs->nactvar; /* free registers */
luaK_patchtohere(fs, bl->breaklist);
@@ -444,6 +445,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
FuncState *fs = ls->fs;
int reg = ls->fs->freereg;
expdesc key, val;
int rkkey;
if (ls->t.token == TK_NAME) {
luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
checkname(ls, &key);
@@ -452,10 +454,9 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
yindex(ls, &key);
cc->nh++;
checknext(ls, '=');
luaK_exp2RK(fs, &key);
rkkey = luaK_exp2RK(fs, &key);
expr(ls, &val);
luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, luaK_exp2RK(fs, &key),
luaK_exp2RK(fs, &val));
luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
fs->freereg = reg; /* free registers */
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lparser.h,v 1.55 2005/04/25 19:24:10 roberto Exp roberto $
** $Id: lparser.h,v 1.56 2005/10/03 14:02:40 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -9,7 +9,6 @@
#include "llimits.h"
#include "lobject.h"
#include "ltable.h"
#include "lzio.h"

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 2.34 2005/09/20 17:55:53 roberto Exp roberto $
** $Id: lstate.c,v 2.35 2005/10/06 20:46:25 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -198,7 +198,6 @@ static void callallgcTM (lua_State *L, void *ud) {
LUA_API void lua_close (lua_State *L) {
L = G(L)->mainthread; /* only the main thread can be closed */
luai_userstateclose(L);
lua_lock(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
@@ -209,6 +208,7 @@ LUA_API void lua_close (lua_State *L) {
L->nCcalls = 0;
} while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
lua_assert(G(L)->tmudata == NULL);
luai_userstateclose(L);
close_state(L);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.129 2005/12/21 12:59:43 roberto Exp roberto $
** $Id: lstrlib.c,v 1.131 2006/04/12 20:13:52 roberto Exp roberto $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -703,6 +703,10 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
luaL_addchar(b, *s);
break;
}
case '\r': {
luaL_addlstring(b, "\\r", 2);
break;
}
case '\0': {
luaL_addlstring(b, "\\000", 4);
break;
@@ -805,7 +809,8 @@ static int str_format (lua_State *L) {
}
}
default: { /* also treat cases `pnLlh' */
return luaL_error(L, "invalid option to " LUA_QL("format"));
return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
LUA_QL("format"), *(strfrmt - 1));
}
}
luaL_addlstring(&b, buff, strlen(buff));

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 2.35 2006/01/10 12:50:00 roberto Exp roberto $
** $Id: ltests.c,v 2.36 2006/01/10 13:13:06 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -82,7 +82,7 @@ static void setnameval (lua_State *L, const char *name, int val) {
#endif
Memcontrol memcontrol = {0L, 0L, 0L, ULONG_MAX};
Memcontrol memcontrol = {0L, 0L, 0L, 0L};
static void *checkblock (void *block, size_t size) {
@@ -109,6 +109,10 @@ static void freeblock (Memcontrol *mc, void *block, size_t size) {
void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) {
Memcontrol *mc = cast(Memcontrol *, ud);
lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
if (mc->memlimit == 0) { /* first time? */
char *limit = getenv("MEMLIMIT"); /* initialize memory limit */
mc->memlimit = limit ? strtoul(limit, NULL, 10) : ULONG_MAX;
}
if (size == 0) {
freeblock(mc, block, oldsize);
return NULL;
@@ -1121,8 +1125,15 @@ static const struct luaL_Reg tests_funcs[] = {
};
static void checkfinalmem (void) {
lua_assert(memcontrol.numblocks == 0);
lua_assert(memcontrol.total == 0);
}
int luaB_opentests (lua_State *L) {
void *ud;
atexit(checkfinalmem);
lua_assert(lua_getallocf(L, &ud) == debug_realloc);
lua_assert(ud == cast(void *, &memcontrol));
lua_setallocf(L, lua_getallocf(L, NULL), ud);
@@ -1131,17 +1142,4 @@ int luaB_opentests (lua_State *L) {
return 0;
}
#undef main
int main (int argc, char *argv[]) {
int ret;
char *limit = getenv("MEMLIMIT");
if (limit)
memcontrol.memlimit = strtoul(limit, NULL, 10);
ret = l_main(argc, argv);
lua_assert(memcontrol.numblocks == 0);
lua_assert(memcontrol.total == 0);
return ret;
}
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltests.h,v 2.16 2005/09/14 17:48:57 roberto Exp roberto $
** $Id: ltests.h,v 2.17 2005/12/27 17:12:00 roberto Exp roberto $
** Internal Header for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -77,12 +77,6 @@ int luaB_opentests (lua_State *L);
/* real main will be defined at `ltests.c' */
int l_main (int argc, char *argv[]);
#define main l_main
/* change some sizes to give some bugs a chance */
#undef LUAL_BUFFERSIZE

31
lua.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.156 2005/12/29 12:30:16 roberto Exp roberto $
** $Id: lua.c,v 1.159 2006/05/24 14:16:39 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -107,7 +107,7 @@ static int docall (lua_State *L, int narg, int clear) {
static void print_version (void) {
l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT);
l_message(NULL, LUA_RELEASE " " LUA_COPYRIGHT);
}
@@ -252,17 +252,30 @@ static int handle_script (lua_State *L, char **argv, int n) {
}
/* check that argument has no extra characters at the end */
#define notail(x) {if ((x)[2] != '\0') return -1;}
static int collectargs (char **argv, int *pi, int *pv, int *pe) {
int i;
for (i = 1; argv[i] != NULL; i++) {
if (argv[i][0] != '-') /* not an option? */
return i;
switch (argv[i][1]) { /* option */
case '-': return (argv[i+1] != NULL ? i+1 : 0);
case '\0': return i;
case 'i': *pi = 1; /* go through */
case 'v': *pv = 1; break;
case 'e': *pe = 1; /* go through */
case '-':
notail(argv[i]);
return (argv[i+1] != NULL ? i+1 : 0);
case '\0':
return i;
case 'i':
notail(argv[i]);
*pi = 1; /* go through */
case 'v':
notail(argv[i]);
*pv = 1;
break;
case 'e':
*pe = 1; /* go through */
case 'l':
if (argv[i][2] == '\0') {
i++;
@@ -306,12 +319,12 @@ static int runargs (lua_State *L, char **argv, int n) {
static int handle_luainit (lua_State *L) {
const char *init = getenv("LUA_INIT");
const char *init = getenv(LUA_INIT);
if (init == NULL) return 0; /* status OK */
else if (init[0] == '@')
return dofile(L, init+1);
else
return dostring(L, init, "=LUA_INIT");
return dostring(L, init, "=" LUA_INIT);
}

3
lua.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.215 2005/12/27 17:09:50 roberto Exp roberto $
** $Id: lua.h,v 1.217 2006/05/31 16:50:40 roberto Exp roberto $
** Lua - An Extensible Extension Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -17,6 +17,7 @@
#define LUA_VERSION "Lua 5.1"
#define LUA_RELEASE "Lua 5.1.1"
#define LUA_VERSION_NUM 501
#define LUA_COPYRIGHT "Copyright (C) 1994-2006 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"

View File

@@ -1,5 +1,5 @@
/*
** $Id: luaconf.h,v 1.80 2006/01/27 13:54:39 roberto Exp roberto $
** $Id: luaconf.h,v 1.81 2006/02/10 17:44:06 roberto Exp roberto $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -59,6 +59,18 @@
#endif
/*
@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
@* Lua check to set its paths.
@@ LUA_INIT is the name of the environment variable that Lua
@* checks for initialization code.
** CHANGE them if you want different names.
*/
#define LUA_PATH "LUA_PATH"
#define LUA_CPATH "LUA_CPATH"
#define LUA_INIT "LUA_INIT"
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@* Lua libraries.
@@ -543,11 +555,25 @@
/* On a Pentium, resort to a trick */
#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
(defined(__i386) || defined (_M_IX86) || defined(__i386__))
/* On a Microsoft compiler, use assembler */
#if defined(_MSC_VER)
#define lua_number2int(i,d) __asm fld d __asm fistp i
#define lua_number2integer(i,n) lua_number2int(i, n)
/* the next trick should work on any Pentium, but sometimes clashes
with a DirectX idiosyncrasy */
#else
union luai_Cast { double l_d; long l_l; };
#define lua_number2int(i,d) \
{ volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n) lua_number2int(i, n)
#endif
/* this option always works, but may be slow */
#else
#define lua_number2int(i,d) ((i)=(int)(d))

3
lvm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 2.61 2006/01/10 12:50:00 roberto Exp roberto $
** $Id: lvm.c,v 2.62 2006/01/23 19:51:43 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -376,6 +376,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
TValue *k;
const Instruction *pc;
reentry: /* entry point */
lua_assert(isLua(L->ci));
pc = L->savedpc;
cl = &clvalue(L->ci->func)->l;
base = L->base;

View File

@@ -18,7 +18,7 @@ LOCAL = $(TESTS) $(CWARNS)
CC= gcc
CFLAGS= -O2 -Wall $(MYCFLAGS)
CFLAGS= -Wall $(MYCFLAGS) -O2
AR= ar rcu
RANLIB= ranlib
RM= rm -f
@@ -75,6 +75,7 @@ $(LUAC_T): $(LUAC_O) $(CORE_T)
$(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(CORE_T) $(LIBS) $(MYLIBS)
clean:
rcsclean -u
$(RM) $(ALL_T) $(ALL_O)
depend: