Compare commits

...

93 Commits

Author SHA1 Message Date
Roberto Ierusalimschy
762c737037 last changes by lhf 2003-04-10 14:39:41 -03:00
Roberto Ierusalimschy
de57dc2653 new scheme to control `loadlib' configuration (default for dlopen
implementation is not to include it)
2003-04-07 17:11:53 -03:00
Roberto Ierusalimschy
d1df829f8d lua_getmetatable must accept any acceptable index 2003-04-07 11:36:08 -03:00
Roberto Ierusalimschy
2ad947fe03 new test options for luaL_getn/setn 2003-04-07 11:35:00 -03:00
Roberto Ierusalimschy
f0cc013afa luaL_getn/setn must operate correctly over negative indices 2003-04-07 11:35:00 -03:00
Roberto Ierusalimschy
0d88545b82 warnings from several compilers (mainly typecasts when lua_Number is float) 2003-04-03 10:35:34 -03:00
Roberto Ierusalimschy
f84c5a5fc6 avoid conflicts in (re)definition of `isatty' 2003-04-03 10:34:42 -03:00
Roberto Ierusalimschy
05d35d8f3c comments 2003-04-02 10:09:14 -03:00
Roberto Ierusalimschy
3a6230ef7c error-message format 2003-04-01 14:52:31 -03:00
Roberto Ierusalimschy
a424a112b5 clearance of debuging code (left by mistake) 2003-03-31 10:00:25 -03:00
Roberto Ierusalimschy
b858161fbc new hash method for lua_Number (double) (due to a performance problem) 2003-03-24 11:18:42 -03:00
Roberto Ierusalimschy
80bac182db do not mix --help' with --' 2003-03-24 09:40:01 -03:00
Roberto Ierusalimschy
30a411ab3c chars from zio are always unsigned 2003-03-24 09:39:34 -03:00
Roberto Ierusalimschy
5bb5a1831d details 2003-03-20 17:26:33 -03:00
Roberto Ierusalimschy
b518d14071 bug: zio mixes a 255 as first char in a buffer with EOZ 2003-03-20 13:00:56 -03:00
Roberto Ierusalimschy
15dbb53461 towards 5.0 final 2003-03-19 18:27:30 -03:00
Roberto Ierusalimschy
abc304f9da avoid name colision (for alllua.c) 2003-03-19 18:24:04 -03:00
Roberto Ierusalimschy
1a553f9199 better error messages 2003-03-19 18:16:12 -03:00
Roberto Ierusalimschy
0ca225d33a better error message 2003-03-19 18:15:18 -03:00
Roberto Ierusalimschy
70e2b7ab86 name changes to avoid name collision between macros and variables 2003-03-19 18:14:53 -03:00
Roberto Ierusalimschy
5a144e891a __globals' -> __fenv' 2003-03-19 18:14:34 -03:00
Roberto Ierusalimschy
b12776f29c `luaL_getmetafield' was leaving extra value on the stack 2003-03-18 15:48:31 -03:00
Roberto Ierusalimschy
ab9e062928 name changes to avoid name collision between macros and variables 2003-03-18 09:50:04 -03:00
Roberto Ierusalimschy
81cdbabf09 detail (change place of a prototype) 2003-03-18 09:31:39 -03:00
Roberto Ierusalimschy
40cfb0691e new auxiliary functions for `type' manipulation 2003-03-18 09:25:32 -03:00
Roberto Ierusalimschy
9b7af7e45b tests for Windows version 2003-03-18 09:25:01 -03:00
Roberto Ierusalimschy
2e66248f8a unused argument 2003-03-18 09:24:38 -03:00
Roberto Ierusalimschy
79db75101e detail 2003-03-18 09:24:26 -03:00
Roberto Ierusalimschy
b0c40e2405 first version of `loadlib' 2003-03-17 10:04:58 -03:00
Roberto Ierusalimschy
4734e2de05 `loadlib' now an official library 2003-03-17 10:01:48 -03:00
Roberto Ierusalimschy
7ea180af6e detail 2003-03-14 16:08:11 -03:00
Roberto Ierusalimschy
05d567d52e io.input'/io.output' always return current file 2003-03-14 16:00:16 -03:00
Roberto Ierusalimschy
d8a3a00d84 `string.find' also accepts out-of-range indices 2003-03-14 15:59:53 -03:00
Roberto Ierusalimschy
c9ea94ec92 out-of-bound upvalues (in C) are acceptable indices 2003-03-14 15:59:21 -03:00
Roberto Ierusalimschy
fa4b4c1100 loadstring/loadfile use global environment + setfenv(0) changes
global environment
2003-03-11 15:17:43 -03:00
Roberto Ierusalimschy
4039bf457d ^ operator is defined by global `__pow' 2003-03-11 09:30:37 -03:00
Roberto Ierusalimschy
034de1fe73 new names for functions that open C libraries 2003-03-11 09:24:34 -03:00
Roberto Ierusalimschy
430d6db928 LUA_PATH components may have multiple interrogation marks 2003-03-11 09:08:13 -03:00
Roberto Ierusalimschy
7c3857cded comments 2003-03-07 10:21:31 -03:00
Roberto Ierusalimschy
8ce6f0b418 avoid including system headers after program headers 2003-03-06 16:37:42 -03:00
Roberto Ierusalimschy
572bddc0b0 LUA_USETMPNAME -> USE_TMPNAME 2003-03-06 16:36:44 -03:00
Roberto Ierusalimschy
3684f67771 details (text of an error message) 2003-03-06 16:36:16 -03:00
Roberto Ierusalimschy
69dd9461e5 bug: GC metamethod calls could mess C/Lua stack syncronization 2003-02-28 16:45:15 -03:00
Roberto Ierusalimschy
6b6bc532a4 better error message for (deprecated) "%global" 2003-02-28 14:19:47 -03:00
Roberto Ierusalimschy
ea16ee41a8 no more attempt to optimize GC when parsing new modules (too complex) 2003-02-28 12:42:08 -03:00
Roberto Ierusalimschy
60d11ec316 by default, gcc does not get tmpname 2003-02-27 09:39:05 -03:00
Roberto Ierusalimschy
e1a424e8a3 avoid the identifier index' (clashes with BSD index' function) 2003-02-27 09:33:07 -03:00
Roberto Ierusalimschy
59ce42dbd5 detail 2003-02-27 09:32:30 -03:00
Roberto Ierusalimschy
92f6e0c1bf no-nonsense debug information about tail calls 2003-02-27 08:52:30 -03:00
Roberto Ierusalimschy
5cd99b82b7 set/getenvtable' -> set/getfenv' 2003-02-24 13:54:20 -03:00
Roberto Ierusalimschy
07e210e655 `require' returns value returned by package 2003-02-24 13:50:41 -03:00
Roberto Ierusalimschy
feb724c122 ULONG_MAX>>10 may not fit into an int (old bug) 2003-02-21 16:00:14 -03:00
Roberto Ierusalimschy
67f9a2a98f details 2003-02-20 17:12:39 -03:00
Roberto Ierusalimschy
c4f9c887fc expressions too complex for an ARM compiler... 2003-02-19 07:28:58 -03:00
Roberto Ierusalimschy
9866fb0ef1 set/getglobals' -> set/getenvtable' 2003-02-18 13:13:15 -03:00
Roberto Ierusalimschy
60c83ded30 small optimization for sizes of array constructors 2003-02-18 13:02:56 -03:00
Roberto Ierusalimschy
07948c3181 restore _REQUIREDNAME after requiring a file 2003-02-18 13:02:13 -03:00
Roberto Ierusalimschy
dce9a49a08 final version 2003-02-18 13:01:57 -03:00
Roberto Ierusalimschy
15db58a2f5 create arg table with correct size 2003-02-13 14:08:47 -02:00
Roberto Ierusalimschy
d6826dbc80 simpler way to count uses 2003-02-13 14:08:32 -02:00
Roberto Ierusalimschy
e75a6ae9ee `defaultmeta' is always empty, but registry needs some space for
names and numbers (references)
2003-02-13 14:07:57 -02:00
Roberto Ierusalimschy
2866fb2dd0 reset _REQUIREDNAME after loading module 2003-02-13 14:07:37 -02:00
Roberto Ierusalimschy
4b6f436d67 unpack' uses getn' to get table size 2003-02-12 07:11:01 -02:00
Roberto Ierusalimschy
8f105d6b59 string.byte returns nil if index is out-of-range 2003-02-12 07:10:41 -02:00
Roberto Ierusalimschy
2fef8c772b auxiliary function to check userdata with types 2003-02-11 13:32:31 -02:00
Roberto Ierusalimschy
7285fa393b use C names for C types 2003-02-11 13:31:50 -02:00
Roberto Ierusalimschy
5085f09ce5 small optimizations 2003-02-11 13:24:52 -02:00
Roberto Ierusalimschy
d674626392 compatibility with '%' syntax is optional 2003-02-11 08:49:53 -02:00
Roberto Ierusalimschy
7a40cdbda0 different variables for number of upvalues and size of upvalue array
(makes code clearer)
2003-02-11 08:46:24 -02:00
Roberto Ierusalimschy
3cdeacbbfb reference system also uses getn/setn (plus small corrections) 2003-02-11 07:44:38 -02:00
Roberto Ierusalimschy
6f207b15fb resist errors in finalizers during lua_close 2003-02-10 15:32:50 -02:00
Roberto Ierusalimschy
3184314bf3 warning 2003-02-10 15:31:13 -02:00
Roberto Ierusalimschy
7964f7cbbd more complete information for coroutine errors 2003-02-10 08:21:31 -02:00
Roberto Ierusalimschy
383a6e88f9 argv[0] may be NULL 2003-01-29 11:23:45 -02:00
Roberto Ierusalimschy
871166d7db test for panic function 2003-01-29 08:27:53 -02:00
Roberto Ierusalimschy
592cf2334e "panic" cannot happen in lua.c, with lua_cpcall +
argv[0] may be empty
2003-01-29 08:27:07 -02:00
Roberto Ierusalimschy
0175f8d5d1 dump/undump of upvalue names 2003-01-27 13:52:57 -02:00
Roberto Ierusalimschy
e79bf02f33 correct semantics for comparison metamethods (they are only valid
when both operands have the same metamethod).
2003-01-27 13:12:52 -02:00
Roberto Ierusalimschy
41ed3c4771 getn/setn in C moved to lauxlib 2003-01-27 11:46:16 -02:00
Roberto Ierusalimschy
635b7c707d details 2003-01-27 11:00:43 -02:00
Roberto Ierusalimschy
83f0d6ef1a DEPRECATED (new manual uses an independent format instead of LaTeX) 2003-01-24 14:38:18 -02:00
Roberto Ierusalimschy
3088ebd95b last changes before leaving Latex 2003-01-24 07:14:54 -02:00
Roberto Ierusalimschy
797d964df9 detail 2003-01-23 09:34:18 -02:00
Roberto Ierusalimschy
e44e579dc1 bug: luaD_protectedparser must protect its garbage collection too 2003-01-23 09:31:38 -02:00
Roberto Ierusalimschy
a153cafd8d starting translation to new format (@comand{...}). 2003-01-22 14:29:38 -02:00
Roberto Ierusalimschy
3b5158f2a1 corrections from Asko Kauppi 2003-01-21 15:45:11 -02:00
Roberto Ierusalimschy
60a8b94fd0 corrections/suggestions by Ed Ferguson 2003-01-20 09:03:05 -02:00
Roberto Ierusalimschy
c499442e5f compatibility macros must be available by default 2003-01-17 13:28:09 -02:00
Roberto Ierusalimschy
9a5bab82ff use the more modern _POSIX_C_SOURCE instead of older _POSIX_SOURCE 2003-01-17 13:27:28 -02:00
Roberto Ierusalimschy
32fd039bb5 `openlib' functions return new module 2002-12-20 08:26:33 -02:00
Roberto Ierusalimschy
75f73172c4 bug: `resume' was checking the wrong value for stack overflow 2002-12-20 07:55:56 -02:00
Roberto Ierusalimschy
754c630754 details 2002-12-19 11:21:08 -02:00
Roberto Ierusalimschy
dd8edecae1 new functions to manipulate upvales (get/setupvalue) 2002-12-19 09:11:55 -02:00
42 changed files with 1419 additions and 5258 deletions

31
bugs
View File

@@ -298,8 +298,39 @@ Fri Aug 30 13:49:14 EST 2002
>> userdata may not be cleared properly
(by Roberto; since 5.0a)
** lapi.c
Thu Nov 21 11:00:00 EST 2002
>> ULONG_MAX>>10 may not fit into an int
(by Jeff Petkau; since 4.0)
** lparser.c
Fri Dec 6 17:06:40 UTC 2002
>> scope of generic for variables is not sound
(by Gavin Wraith; since 5.0a)
=================================================================
--- Version 5.0 beta
** lbaselib.c
Fri Dec 20 09:53:19 UTC 2002
>> `resume' was checking the wrong value for stack overflow
(by Maik Zimmermann; since 5.0b)
** ldo.c
Thu Jan 23 11:29:06 UTC 2003
>> error during garbage collection in luaD_protectedparser is not being
>> protected
(by Benoit Germain; since 5.0a)
** ldo.c (and others)
Fri Feb 28 14:20:33 EST 2003
>> GC metamethod calls could mess C/Lua stack syncronization
(by Roberto; since 5.0b)
** lzio.h/zlio.c
Thu Mar 20 11:40:12 EST 2003
>> zio mixes a 255 as first char in a buffer with EOZ
(by lhf; since 5.0a)

248
lapi.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 1.225 2002/12/04 17:28:27 roberto Exp roberto $
** $Id: lapi.c,v 1.234 2003/04/03 13:35:34 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -45,43 +45,48 @@ const char lua_ident[] =
static TObject *negindex (lua_State *L, int index) {
if (index > LUA_REGISTRYINDEX) {
api_check(L, index != 0 && -index <= L->top - L->base);
return L->top+index;
static TObject *negindex (lua_State *L, int idx) {
if (idx > LUA_REGISTRYINDEX) {
api_check(L, idx != 0 && -idx <= L->top - L->base);
return L->top+idx;
}
else switch (index) { /* pseudo-indices */
else switch (idx) { /* pseudo-indices */
case LUA_REGISTRYINDEX: return registry(L);
case LUA_GLOBALSINDEX: return gt(L);
default: {
TObject *func = (L->base - 1);
index = LUA_GLOBALSINDEX - index;
api_check(L, iscfunction(func) && index <= clvalue(func)->c.nupvalues);
return &clvalue(func)->c.upvalue[index-1];
idx = LUA_GLOBALSINDEX - idx;
lua_assert(iscfunction(func));
return (idx <= clvalue(func)->c.nupvalues)
? &clvalue(func)->c.upvalue[idx-1]
: NULL;
}
}
}
static TObject *luaA_index (lua_State *L, int index) {
if (index > 0) {
api_check(L, index <= L->top - L->base);
return L->base + index - 1;
static TObject *luaA_index (lua_State *L, int idx) {
if (idx > 0) {
api_check(L, idx <= L->top - L->base);
return L->base + idx - 1;
}
else {
TObject *o = negindex(L, idx);
api_check(L, o != NULL);
return o;
}
else
return negindex(L, index);
}
static TObject *luaA_indexAcceptable (lua_State *L, int index) {
if (index > 0) {
TObject *o = L->base+(index-1);
api_check(L, index <= L->stack_last - L->base);
static TObject *luaA_indexAcceptable (lua_State *L, int idx) {
if (idx > 0) {
TObject *o = L->base+(idx-1);
api_check(L, idx <= L->stack_last - L->base);
if (o >= L->top) return NULL;
else return o;
}
else
return negindex(L, index);
return negindex(L, idx);
}
@@ -154,55 +159,55 @@ LUA_API int lua_gettop (lua_State *L) {
}
LUA_API void lua_settop (lua_State *L, int index) {
LUA_API void lua_settop (lua_State *L, int idx) {
lua_lock(L);
if (index >= 0) {
api_check(L, index <= L->stack_last - L->base);
while (L->top < L->base + index)
if (idx >= 0) {
api_check(L, idx <= L->stack_last - L->base);
while (L->top < L->base + idx)
setnilvalue(L->top++);
L->top = L->base + index;
L->top = L->base + idx;
}
else {
api_check(L, -(index+1) <= (L->top - L->base));
L->top += index+1; /* `subtract' index (index is negative) */
api_check(L, -(idx+1) <= (L->top - L->base));
L->top += idx+1; /* `subtract' index (index is negative) */
}
lua_unlock(L);
}
LUA_API void lua_remove (lua_State *L, int index) {
LUA_API void lua_remove (lua_State *L, int idx) {
StkId p;
lua_lock(L);
p = luaA_index(L, index);
p = luaA_index(L, idx);
while (++p < L->top) setobjs2s(p-1, p);
L->top--;
lua_unlock(L);
}
LUA_API void lua_insert (lua_State *L, int index) {
LUA_API void lua_insert (lua_State *L, int idx) {
StkId p;
StkId q;
lua_lock(L);
p = luaA_index(L, index);
p = luaA_index(L, idx);
for (q = L->top; q>p; q--) setobjs2s(q, q-1);
setobjs2s(p, L->top);
lua_unlock(L);
}
LUA_API void lua_replace (lua_State *L, int index) {
LUA_API void lua_replace (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 1);
setobj(luaA_index(L, index), L->top - 1); /* write barrier */
setobj(luaA_index(L, idx), L->top - 1); /* write barrier */
L->top--;
lua_unlock(L);
}
LUA_API void lua_pushvalue (lua_State *L, int index) {
LUA_API void lua_pushvalue (lua_State *L, int idx) {
lua_lock(L);
setobj2s(L->top, luaA_index(L, index));
setobj2s(L->top, luaA_index(L, idx));
api_incr_top(L);
lua_unlock(L);
}
@@ -214,8 +219,8 @@ LUA_API void lua_pushvalue (lua_State *L, int index) {
*/
LUA_API int lua_type (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API int lua_type (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
return (o == NULL) ? LUA_TNONE : ttype(o);
}
@@ -226,27 +231,27 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
}
LUA_API int lua_iscfunction (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API int lua_iscfunction (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
return (o == NULL) ? 0 : iscfunction(o);
}
LUA_API int lua_isnumber (lua_State *L, int index) {
LUA_API int lua_isnumber (lua_State *L, int idx) {
TObject n;
const TObject *o = luaA_indexAcceptable(L, index);
const TObject *o = luaA_indexAcceptable(L, idx);
return (o != NULL && tonumber(o, &n));
}
LUA_API int lua_isstring (lua_State *L, int index) {
int t = lua_type(L, index);
LUA_API int lua_isstring (lua_State *L, int idx) {
int t = lua_type(L, idx);
return (t == LUA_TSTRING || t == LUA_TNUMBER);
}
LUA_API int lua_isuserdata (lua_State *L, int index) {
const TObject *o = luaA_indexAcceptable(L, index);
LUA_API int lua_isuserdata (lua_State *L, int idx) {
const TObject *o = luaA_indexAcceptable(L, idx);
return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
}
@@ -286,9 +291,9 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
TObject n;
const TObject *o = luaA_indexAcceptable(L, index);
const TObject *o = luaA_indexAcceptable(L, idx);
if (o != NULL && tonumber(o, &n))
return nvalue(o);
else
@@ -296,14 +301,14 @@ LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
}
LUA_API int lua_toboolean (lua_State *L, int index) {
const TObject *o = luaA_indexAcceptable(L, index);
LUA_API int lua_toboolean (lua_State *L, int idx) {
const TObject *o = luaA_indexAcceptable(L, idx);
return (o != NULL) && !l_isfalse(o);
}
LUA_API const char *lua_tostring (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API const char *lua_tostring (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
if (o == NULL)
return NULL;
else if (ttisstring(o))
@@ -319,8 +324,8 @@ LUA_API const char *lua_tostring (lua_State *L, int index) {
}
LUA_API size_t lua_strlen (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API size_t lua_strlen (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
if (o == NULL)
return 0;
else if (ttisstring(o))
@@ -335,14 +340,14 @@ LUA_API size_t lua_strlen (lua_State *L, int index) {
}
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->c.f;
}
LUA_API void *lua_touserdata (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API void *lua_touserdata (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
if (o == NULL) return NULL;
switch (ttype(o)) {
case LUA_TUSERDATA: return (uvalue(o) + 1);
@@ -352,22 +357,23 @@ LUA_API void *lua_touserdata (lua_State *L, int index) {
}
LUA_API lua_State *lua_tothread (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
return (o == NULL || !ttisthread(o)) ? NULL : thvalue(o);
}
LUA_API const void *lua_topointer (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
LUA_API const void *lua_topointer (lua_State *L, int idx) {
StkId o = luaA_indexAcceptable(L, idx);
if (o == NULL) return NULL;
else {
switch (ttype(o)) {
case LUA_TTABLE: return hvalue(o);
case LUA_TFUNCTION: return clvalue(o);
case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, index);
return lua_touserdata(L, idx);
default: return NULL;
}
}
@@ -475,29 +481,29 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
*/
LUA_API void lua_gettable (lua_State *L, int index) {
LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = luaA_index(L, index);
t = luaA_index(L, idx);
setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
lua_unlock(L);
}
LUA_API void lua_rawget (lua_State *L, int index) {
LUA_API void lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = luaA_index(L, index);
t = luaA_index(L, idx);
api_check(L, ttistable(t));
setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
lua_unlock(L);
}
LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
StkId o;
lua_lock(L);
o = luaA_index(L, index);
o = luaA_index(L, idx);
api_check(L, ttistable(o));
setobj2s(L->top, luaH_getnum(hvalue(o), n));
api_incr_top(L);
@@ -515,22 +521,22 @@ LUA_API void lua_newtable (lua_State *L) {
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
StkId obj;
Table *mt;
const TObject *obj;
Table *mt = NULL;
int res;
lua_lock(L);
obj = luaA_indexAcceptable(L, objindex);
switch (ttype(obj)) {
case LUA_TTABLE:
mt = hvalue(obj)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(obj)->uv.metatable;
break;
default:
mt = hvalue(defaultmeta(L));
if (obj != NULL) {
switch (ttype(obj)) {
case LUA_TTABLE:
mt = hvalue(obj)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(obj)->uv.metatable;
break;
}
}
if (mt == hvalue(defaultmeta(L)))
if (mt == NULL || mt == hvalue(defaultmeta(L)))
res = 0;
else {
sethvalue(L->top, mt);
@@ -542,10 +548,10 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
}
LUA_API void lua_getglobals (lua_State *L, int index) {
LUA_API void lua_getfenv (lua_State *L, int idx) {
StkId o;
lua_lock(L);
o = luaA_index(L, index);
o = luaA_index(L, idx);
setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
api_incr_top(L);
lua_unlock(L);
@@ -557,22 +563,22 @@ LUA_API void lua_getglobals (lua_State *L, int index) {
*/
LUA_API void lua_settable (lua_State *L, int index) {
LUA_API void lua_settable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
api_checknelems(L, 2);
t = luaA_index(L, index);
t = luaA_index(L, idx);
luaV_settable(L, t, L->top - 2, L->top - 1);
L->top -= 2; /* pop index and value */
lua_unlock(L);
}
LUA_API void lua_rawset (lua_State *L, int index) {
LUA_API void lua_rawset (lua_State *L, int idx) {
StkId t;
lua_lock(L);
api_checknelems(L, 2);
t = luaA_index(L, index);
t = luaA_index(L, idx);
api_check(L, ttistable(t));
setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */
L->top -= 2;
@@ -580,11 +586,11 @@ LUA_API void lua_rawset (lua_State *L, int index) {
}
LUA_API void lua_rawseti (lua_State *L, int index, int n) {
LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
StkId o;
lua_lock(L);
api_checknelems(L, 1);
o = luaA_index(L, index);
o = luaA_index(L, idx);
api_check(L, ttistable(o));
setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */
L->top--;
@@ -620,12 +626,12 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
}
LUA_API int lua_setglobals (lua_State *L, int index) {
LUA_API int lua_setfenv (lua_State *L, int idx) {
StkId o;
int res = 0;
lua_lock(L);
api_checknelems(L, 1);
o = luaA_index(L, index);
o = luaA_index(L, idx);
L->top--;
api_check(L, ttistable(L->top));
if (isLfunction(o)) {
@@ -676,7 +682,7 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
c.func = L->top - (nargs+1); /* function to be called */
c.nresults = nresults;
status = luaD_pcall(L, &f_call, &c, savestack(L, c.func), func);
status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func);
lua_unlock(L);
return status;
}
@@ -710,7 +716,7 @@ LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
lua_lock(L);
c.func = func;
c.ud = ud;
status = luaD_pcall(L, &f_Ccall, &c, savestack(L, L->top), 0);
status = luaD_pcall(L, f_Ccall, &c, savestack(L, L->top), 0);
lua_unlock(L);
return status;
}
@@ -755,7 +761,7 @@ LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
/* GC values are expressed in Kbytes: #bytes/2^10 */
#define GCscalel(x) ((x)>>10)
#define GCscale(x) (cast(int, GCscalel(x)))
#define GCunscale(x) (cast(lu_mem, (x)<<10))
#define GCunscale(x) (cast(lu_mem, x)<<10)
LUA_API int lua_getgcthreshold (lua_State *L) {
int threshold;
@@ -775,8 +781,8 @@ LUA_API int lua_getgccount (lua_State *L) {
LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
lua_lock(L);
if (cast(lu_mem, newthreshold) > GCscalel(ULONG_MAX))
G(L)->GCthreshold = ULONG_MAX;
if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
G(L)->GCthreshold = MAX_LUMEM;
else
G(L)->GCthreshold = GCunscale(newthreshold);
luaC_checkGC(L);
@@ -803,11 +809,11 @@ LUA_API int lua_error (lua_State *L) {
}
LUA_API int lua_next (lua_State *L, int index) {
LUA_API int lua_next (lua_State *L, int idx) {
StkId t;
int more;
lua_lock(L);
t = luaA_index(L, index);
t = luaA_index(L, idx);
api_check(L, ttistable(t));
more = luaH_next(L, hvalue(t), L->top - 1);
if (more) {
@@ -866,3 +872,51 @@ LUA_API int lua_pushupvalues (lua_State *L) {
}
static const char *aux_upvalue (lua_State *L, int funcindex, int n,
TObject **val) {
Closure *f;
StkId fi = luaA_index(L, funcindex);
if (!ttisfunction(fi)) return NULL;
f = clvalue(fi);
if (f->c.isC) {
if (n > f->c.nupvalues) return NULL;
*val = &f->c.upvalue[n-1];
return "";
}
else {
Proto *p = f->l.p;
if (n > p->sizeupvalues) return NULL;
*val = f->l.upvals[n-1]->v;
return getstr(p->upvalues[n-1]);
}
}
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TObject *val;
lua_lock(L);
name = aux_upvalue(L, funcindex, n, &val);
if (name) {
setobj2s(L->top, val);
api_incr_top(L);
}
lua_unlock(L);
return name;
}
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TObject *val;
lua_lock(L);
api_checknelems(L, 1);
name = aux_upvalue(L, funcindex, n, &val);
if (name) {
L->top--;
setobj(val, L->top); /* write barrier */
}
lua_unlock(L);
return name;
}

171
lauxlib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.c,v 1.90 2002/11/14 15:41:38 roberto Exp roberto $
** $Id: lauxlib.c,v 1.99 2003/04/03 13:35:34 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -23,6 +23,19 @@
#include "lauxlib.h"
/* number of prereserved references (for internal use) */
#define RESERVED_REFS 2
/* reserved references */
#define FREELIST_REF 1 /* free list of references */
#define ARRAYSIZE_REF 2 /* array sizes */
/* convert a stack index to positive */
#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
lua_gettop(L) + (i) + 1)
/*
** {======================================================
** Error-report functions
@@ -37,9 +50,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
if (strcmp(ar.namewhat, "method") == 0) {
narg--; /* do not count `self' */
if (narg == 0) /* error is in the self argument itself? */
return luaL_error(L,
"calling %s on bad self (perhaps using `:' instead of `.')",
ar.name);
return luaL_error(L, "calling `%s' on bad self (%s)", ar.name, extramsg);
}
if (ar.name == NULL)
ar.name = "?";
@@ -95,6 +106,45 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) {
}
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
lua_pushstring(L, tname);
lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
lua_newtable(L); /* create metatable */
lua_pushstring(L, tname);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */
lua_pushvalue(L, -1);
lua_pushstring(L, tname);
lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */
return 1;
}
LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) {
lua_pushstring(L, tname);
lua_rawget(L, LUA_REGISTRYINDEX);
}
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
const char *tn;
if (!lua_getmetatable(L, ud)) return NULL; /* no metatable? */
lua_rawget(L, LUA_REGISTRYINDEX); /* get registry[metatable] */
tn = lua_tostring(L, -1);
if (tn && (strcmp(tn, tname) == 0)) {
lua_pop(L, 1);
return lua_touserdata(L, ud);
}
else {
lua_pop(L, 1);
return NULL;
}
}
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
if (!lua_checkstack(L, space))
luaL_error(L, "stack overflow (%s)", mes);
@@ -155,11 +205,15 @@ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
lua_pop(L, 2); /* remove metatable and metafield */
return 0;
}
return 1;
else {
lua_remove(L, -2); /* remove only metatable */
return 1;
}
}
LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
obj = abs_index(L, obj);
if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
return 0;
lua_pushvalue(L, obj);
@@ -176,6 +230,9 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
if (lua_isnil(L, -1)) { /* no? */
lua_pop(L, 1);
lua_newtable(L); /* create it */
lua_pushstring(L, libname);
lua_pushvalue(L, -2);
lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */
}
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
}
@@ -188,14 +245,81 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
lua_settable(L, -(nup+3));
}
lua_pop(L, nup); /* remove upvalues */
if (libname) {
lua_pushstring(L, libname);
lua_pushvalue(L, -2);
lua_settable(L, LUA_GLOBALSINDEX);
}
/*
** {======================================================
** getn-setn: size for arrays
** =======================================================
*/
static int checkint (lua_State *L, int topop) {
int n = (int)lua_tonumber(L, -1);
if (n == 0 && !lua_isnumber(L, -1)) n = -1;
lua_pop(L, topop);
return n;
}
static void getsizes (lua_State *L) {
lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
if (lua_isnil(L, -1)) { /* no `size' table? */
lua_pop(L, 1); /* remove nil */
lua_newtable(L); /* create it */
lua_pushvalue(L, -1); /* `size' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, "__mode");
lua_pushliteral(L, "k");
lua_rawset(L, -3); /* metatable(N).__mode = "k" */
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */
}
}
void luaL_setn (lua_State *L, int t, int n) {
t = abs_index(L, t);
lua_pushliteral(L, "n");
lua_rawget(L, t);
if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */
lua_pushliteral(L, "n"); /* use it */
lua_pushnumber(L, (lua_Number)n);
lua_rawset(L, t);
}
else { /* use `sizes' */
getsizes(L);
lua_pushvalue(L, t);
lua_pushnumber(L, (lua_Number)n);
lua_rawset(L, -3); /* sizes[t] = n */
lua_pop(L, 1); /* remove `sizes' */
}
}
int luaL_getn (lua_State *L, int t) {
int n;
t = abs_index(L, t);
lua_pushliteral(L, "n"); /* try t.n */
lua_rawget(L, t);
if ((n = checkint(L, 1)) >= 0) return n;
getsizes(L); /* else try sizes[t] */
lua_pushvalue(L, t);
lua_rawget(L, -2);
if ((n = checkint(L, 2)) >= 0) return n;
for (n = 1; ; n++) { /* else must count elements */
lua_rawgeti(L, t, n);
if (lua_isnil(L, -1)) break;
lua_pop(L, 1);
}
lua_pop(L, 1);
return n - 1;
}
/* }====================================================== */
/*
** {======================================================
@@ -204,7 +328,6 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
*/
#define buffempty(B) ((B)->p == (B)->buffer)
#define bufflen(B) ((B)->p - (B)->buffer)
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
@@ -295,25 +418,24 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
LUALIB_API int luaL_ref (lua_State *L, int t) {
int ref;
t = abs_index(L, t);
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
lua_rawgeti(L, t, 0); /* get first free element */
ref = (int)lua_tonumber(L, -1); /* ref = t[0] */
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
lua_rawseti(L, t, 0); /* (that is, t[0] = t[ref]) */
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
}
else { /* no free elements */
lua_pushliteral(L, "n");
lua_pushvalue(L, -1);
lua_rawget(L, t); /* get t.n */
ref = (int)lua_tonumber(L, -1) + 1; /* ref = t.n + 1 */
lua_pop(L, 1); /* pop t.n */
lua_pushnumber(L, ref);
lua_rawset(L, t); /* t.n = t.n + 1 */
ref = luaL_getn(L, t);
if (ref < RESERVED_REFS)
ref = RESERVED_REFS; /* skip reserved references */
ref++; /* create new reference */
luaL_setn(L, t, ref);
}
lua_rawseti(L, t, ref);
return ref;
@@ -322,10 +444,11 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
if (ref >= 0) {
lua_rawgeti(L, t, 0);
lua_rawseti(L, t, ref); /* t[ref] = t[0] */
lua_pushnumber(L, ref);
lua_rawseti(L, t, 0); /* t[0] = ref */
t = abs_index(L, t);
lua_rawgeti(L, t, FREELIST_REF);
lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
lua_pushnumber(L, (lua_Number)ref);
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
}
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lauxlib.h,v 1.54 2002/09/16 19:49:45 roberto Exp roberto $
** $Id: lauxlib.h,v 1.59 2003/03/18 12:25:32 roberto Exp roberto $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -16,7 +16,7 @@
#ifndef LUALIB_API
#define LUALIB_API extern
#define LUALIB_API LUA_API
#endif
@@ -43,6 +43,10 @@ LUALIB_API void luaL_checkstack (lua_State *L, int sz, const char *msg);
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t);
LUALIB_API void luaL_checkany (lua_State *L, int narg);
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname);
LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname);
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname);
LUALIB_API void luaL_where (lua_State *L, int lvl);
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
@@ -51,6 +55,9 @@ LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
LUALIB_API int luaL_ref (lua_State *L, int t);
LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
LUALIB_API int luaL_getn (lua_State *L, int t);
LUALIB_API void luaL_setn (lua_State *L, int t, int n);
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
const char *name);
@@ -69,8 +76,8 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n) ((int)luaL_checknumber(L, n))
#define luaL_checklong(L,n) ((long)luaL_checknumber(L, n))
#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,d))
#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,d))
#define luaL_optint(L,n,d) ((int)luaL_optnumber(L, n,(lua_Number)(d)))
#define luaL_optlong(L,n,d) ((long)luaL_optnumber(L, n,(lua_Number)(d)))
/*
@@ -111,7 +118,7 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B);
/*
** Compatibility macros
** Compatibility macros and functions
*/
LUALIB_API int lua_dofile (lua_State *L, const char *filename);
@@ -119,7 +126,7 @@ LUALIB_API int lua_dostring (lua_State *L, const char *str);
LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz,
const char *n);
/*
#define luaL_check_lstr luaL_checklstring
#define luaL_opt_lstr luaL_optlstring
#define luaL_check_number luaL_checknumber
@@ -131,7 +138,7 @@ LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t sz,
#define luaL_check_long luaL_checklong
#define luaL_opt_int luaL_optint
#define luaL_opt_long luaL_optlong
*/
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lbaselib.c,v 1.114 2002/12/04 17:38:31 roberto Exp roberto $
** $Id: lbaselib.c,v 1.129 2003/03/19 21:14:34 roberto Exp roberto $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -66,7 +66,7 @@ static int luaB_tonumber (lua_State *L) {
if (s1 != s2) { /* at least one valid digit? */
while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
if (*s2 == '\0') { /* no invalid trailing characters? */
lua_pushnumber(L, n);
lua_pushnumber(L, (lua_Number)n);
return 1;
}
}
@@ -123,36 +123,41 @@ static void getfunc (lua_State *L) {
if (lua_getstack(L, level, &ar) == 0)
luaL_argerror(L, 1, "invalid level");
lua_getinfo(L, "f", &ar);
if (lua_isnil(L, -1))
luaL_error(L, "no function environment for tail call at level %d",
level);
}
}
static int aux_getglobals (lua_State *L) {
lua_getglobals(L, -1);
lua_pushliteral(L, "__globals");
static int aux_getfenv (lua_State *L) {
lua_getfenv(L, -1);
lua_pushliteral(L, "__fenv");
lua_rawget(L, -2);
return !lua_isnil(L, -1);
}
static int luaB_getglobals (lua_State *L) {
static int luaB_getfenv (lua_State *L) {
getfunc(L);
if (!aux_getglobals(L)) /* __globals not defined? */
lua_pop(L, 1); /* remove it, to return real globals */
if (!aux_getfenv(L)) /* __fenv not defined? */
lua_pop(L, 1); /* remove it, to return real environment */
return 1;
}
static int luaB_setglobals (lua_State *L) {
static int luaB_setfenv (lua_State *L) {
luaL_checktype(L, 2, LUA_TTABLE);
getfunc(L);
if (aux_getglobals(L)) /* __globals defined? */
luaL_error(L, "cannot change a protected global table");
if (aux_getfenv(L)) /* __fenv defined? */
luaL_error(L, "`setfenv' cannot change a protected environment");
else
lua_pop(L, 2); /* remove __globals and real global table */
lua_pop(L, 2); /* remove __fenv and real environment table */
lua_pushvalue(L, 2);
if (lua_setglobals(L, -2) == 0)
luaL_error(L, "cannot change global table of given function");
if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0)
lua_replace(L, LUA_GLOBALSINDEX);
else if (lua_setfenv(L, -2) == 0)
luaL_error(L, "`setfenv' cannot change environment of given function");
return 0;
}
@@ -182,8 +187,8 @@ static int luaB_rawset (lua_State *L) {
static int luaB_gcinfo (lua_State *L) {
lua_pushnumber(L, lua_getgccount(L));
lua_pushnumber(L, lua_getgcthreshold(L));
lua_pushnumber(L, (lua_Number)lua_getgccount(L));
lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L));
return 2;
}
@@ -243,19 +248,12 @@ static int luaB_ipairs (lua_State *L) {
static int load_aux (lua_State *L, int status) {
if (status == 0) { /* OK? */
lua_Debug ar;
lua_getstack(L, 1, &ar);
lua_getinfo(L, "f", &ar); /* get calling function */
lua_getglobals(L, -1); /* get its global table */
lua_setglobals(L, -3); /* set it as the global table of the new chunk */
lua_pop(L, 1); /* remove calling function */
if (status == 0) /* OK? */
return 1;
}
else {
lua_pushnil(L);
lua_insert(L, -2);
return 2;
lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */
}
}
@@ -295,20 +293,11 @@ static int luaB_assert (lua_State *L) {
static int luaB_unpack (lua_State *L) {
int n, i;
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushliteral(L, "n");
lua_rawget(L, 1);
n = (lua_isnumber(L, -1)) ? (int)lua_tonumber(L, -1) : -1;
for (i=0; i<n || n==-1; i++) { /* push arg[1...n] */
luaL_checkstack(L, LUA_MINSTACK, "table too big to unpack");
lua_rawgeti(L, 1, i+1);
if (n == -1) { /* no explicit limit? */
if (lua_isnil(L, -1)) { /* stop at first `nil' element */
lua_pop(L, 1); /* remove `nil' */
break;
}
}
}
return i;
n = luaL_getn(L, 1);
luaL_checkstack(L, n, "table too big to unpack");
for (i=1; i<=n; i++) /* push arg[1...n] */
lua_rawgeti(L, 1, i);
return n;
}
@@ -414,6 +403,10 @@ static int luaB_newproxy (lua_State *L) {
#define LUA_PATH_SEP ';'
#endif
#ifndef LUA_PATH_MARK
#define LUA_PATH_MARK '?'
#endif
#ifndef LUA_PATH_DEFAULT
#define LUA_PATH_DEFAULT "?;?.lua"
#endif
@@ -444,12 +437,18 @@ static const char *pushnextpath (lua_State *L, const char *path) {
static void pushcomposename (lua_State *L) {
const char *path = lua_tostring(L, -1);
const char *wild = strchr(path, '?');
if (wild == NULL) return; /* no wild char; path is the file name */
lua_pushlstring(L, path, wild - path);
lua_pushvalue(L, 1); /* package name */
lua_pushstring(L, wild + 1);
lua_concat(L, 3);
const char *wild;
int n = 1;
while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) {
/* is there stack space for prefix, name, and eventual last sufix? */
luaL_checkstack(L, 3, "too many marks in a path component");
lua_pushlstring(L, path, wild - path); /* push prefix */
lua_pushvalue(L, 1); /* push package name (in place of MARK) */
path = wild + 1; /* continue after MARK */
n += 2;
}
lua_pushstring(L, path); /* push last sufix (`n' already includes this) */
lua_concat(L, n);
}
@@ -458,15 +457,13 @@ static int luaB_require (lua_State *L) {
int status = LUA_ERRFILE; /* not found (yet) */
luaL_checkstring(L, 1);
lua_settop(L, 1);
lua_pushvalue(L, 1);
lua_setglobal(L, "_REQUIREDNAME");
lua_getglobal(L, REQTAB);
if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table");
path = getpath(L);
lua_pushvalue(L, 1); /* check package's name in book-keeping table */
lua_rawget(L, 2);
if (!lua_isnil(L, -1)) /* is it there? */
return 0; /* package is already loaded */
if (lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded; return its result */
else { /* must load it */
while (status == LUA_ERRFILE) {
lua_settop(L, 3); /* reset stack position */
@@ -477,18 +474,29 @@ static int luaB_require (lua_State *L) {
}
switch (status) {
case 0: {
lua_call(L, 0, 0); /* run loaded module */
lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */
lua_insert(L, -2); /* put it below function */
lua_pushvalue(L, 1);
lua_pushboolean(L, 1);
lua_setglobal(L, "_REQUIREDNAME"); /* set new name */
lua_call(L, 0, 1); /* run loaded module */
lua_insert(L, -2); /* put result below previous name */
lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */
if (lua_isnil(L, -1)) { /* no/nil return? */
lua_pushboolean(L, 1);
lua_replace(L, -2); /* replace to true */
}
lua_pushvalue(L, 1);
lua_pushvalue(L, -2);
lua_rawset(L, 2); /* mark it as loaded */
return 0;
return 1; /* return value */
}
case LUA_ERRFILE: { /* file not found */
return luaL_error(L, "could not load package `%s' from path `%s'",
lua_tostring(L, 1), getpath(L));
}
default: {
return luaL_error(L, "error loading package\n%s", lua_tostring(L, -1));
return luaL_error(L, "error loading package `%s' (%s)",
lua_tostring(L, 1), lua_tostring(L, -1));
}
}
}
@@ -500,8 +508,8 @@ static const luaL_reg base_funcs[] = {
{"error", luaB_error},
{"getmetatable", luaB_getmetatable},
{"setmetatable", luaB_setmetatable},
{"getglobals", luaB_getglobals},
{"setglobals", luaB_setglobals},
{"getfenv", luaB_getfenv},
{"setfenv", luaB_setfenv},
{"next", luaB_next},
{"ipairs", luaB_ipairs},
{"pairs", luaB_pairs},
@@ -540,7 +548,7 @@ static int auxresume (lua_State *L, lua_State *co, int narg) {
status = lua_resume(co, narg);
if (status == 0) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, narg))
if (!lua_checkstack(L, nres))
luaL_error(L, "too many results to resume");
lua_xmove(co, L, nres); /* move yielded values */
return nres;
@@ -573,7 +581,14 @@ static int luaB_coresume (lua_State *L) {
static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r < 0) lua_error(L); /* propagate error */
if (r < 0) {
if (lua_isstring(L, -1)) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);
}
lua_error(L); /* propagate error */
}
return r;
}
@@ -649,7 +664,7 @@ static void base_open (lua_State *L) {
}
LUALIB_API int lua_baselibopen (lua_State *L) {
LUALIB_API int luaopen_base (lua_State *L) {
base_open(L);
luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0);
lua_newtable(L);

12
lcode.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lcode.c,v 1.114 2002/12/04 17:38:31 roberto Exp roberto $
** $Id: lcode.c,v 1.116 2003/02/27 12:33:07 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -207,17 +207,17 @@ static void freeexp (FuncState *fs, expdesc *e) {
static int addk (FuncState *fs, TObject *k, TObject *v) {
const TObject *index = luaH_get(fs->h, k);
if (ttisnumber(index)) {
lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(index))], v));
return cast(int, nvalue(index));
const TObject *idx = luaH_get(fs->h, k);
if (ttisnumber(idx)) {
lua_assert(luaO_rawequalObj(&fs->f->k[cast(int, nvalue(idx))], v));
return cast(int, nvalue(idx));
}
else { /* constant not found; create a new entry */
Proto *f = fs->f;
luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject,
MAXARG_Bx, "constant table overflow");
setobj2n(&f->k[fs->nk], v);
setnvalue(luaH_set(fs->L, fs->h, k), fs->nk);
setnvalue(luaH_set(fs->L, fs->h, k), cast(lua_Number, fs->nk));
return fs->nk++;
}
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ldblib.c,v 1.74 2002/12/04 17:38:31 roberto Exp roberto $
** $Id: ldblib.c,v 1.79 2003/03/11 12:24:34 roberto Exp roberto $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -27,7 +27,7 @@ static void settabss (lua_State *L, const char *i, const char *v) {
static void settabsi (lua_State *L, const char *i, int v) {
lua_pushstring(L, i);
lua_pushnumber(L, v);
lua_pushnumber(L, (lua_Number)v);
lua_rawset(L, -3);
}
@@ -108,17 +108,43 @@ static int setlocal (lua_State *L) {
}
static int auxupvalue (lua_State *L, int get) {
const char *name;
int n = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION);
if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == NULL) return 0;
lua_pushstring(L, name);
lua_insert(L, -(get+1));
return get + 1;
}
static int getupvalue (lua_State *L) {
return auxupvalue(L, 1);
}
static int setupvalue (lua_State *L) {
luaL_checkany(L, 3);
return auxupvalue(L, 0);
}
static const char KEY_HOOK = 'h';
static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] = {"call", "return", "line", "count"};
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail return"};
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar->event]);
if (ar->currentline >= 0) lua_pushnumber(L, ar->currentline);
if (ar->currentline >= 0)
lua_pushnumber(L, (lua_Number)ar->currentline);
else lua_pushnil(L);
lua_assert(lua_getinfo(L, "lS", ar));
lua_call(L, 2, 0);
@@ -177,7 +203,7 @@ static int gethook (lua_State *L) {
lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */
}
lua_pushstring(L, unmakemask(mask, buff));
lua_pushnumber(L, lua_gethookcount(L));
lua_pushnumber(L, (lua_Number)lua_gethookcount(L));
return 3;
}
@@ -235,8 +261,8 @@ static int errorfb (lua_State *L) {
default: {
if (*ar.what == 'm') /* main? */
lua_pushfstring(L, " in main chunk");
else if (*ar.what == 'C') /* C function? */
lua_pushfstring(L, "%s", ar.short_src);
else if (*ar.what == 'C' || *ar.what == 't')
lua_pushliteral(L, " ?"); /* C function or tail call */
else
lua_pushfstring(L, " in function <%s:%d>",
ar.short_src, ar.linedefined);
@@ -253,19 +279,21 @@ static const luaL_reg dblib[] = {
{"getlocal", getlocal},
{"getinfo", getinfo},
{"gethook", gethook},
{"getupvalue", getupvalue},
{"sethook", sethook},
{"setlocal", setlocal},
{"setupvalue", setupvalue},
{"debug", debug},
{"traceback", errorfb},
{NULL, NULL}
};
LUALIB_API int lua_dblibopen (lua_State *L) {
LUALIB_API int luaopen_debug (lua_State *L) {
luaL_openlib(L, LUA_DBLIBNAME, dblib, 0);
lua_pushliteral(L, "_TRACEBACK");
lua_pushcfunction(L, errorfb);
lua_settable(L, LUA_GLOBALSINDEX);
return 0;
return 1;
}

151
ldebug.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldebug.c,v 1.142 2002/12/06 17:15:35 roberto Exp roberto $
** $Id: ldebug.c,v 1.149 2003/03/18 12:50:04 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -93,13 +93,21 @@ LUA_API int lua_gethookcount (lua_State *L) {
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
int ci;
CallInfo *ci;
lua_lock(L);
ci = (L->ci - L->base_ci) - level;
if (ci <= 0) status = 0; /* there is no such level */
else {
ar->i_ci = ci;
for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
level--;
if (!(ci->state & CI_C)) /* Lua function? */
level -= ci->u.l.tailcalls; /* skip lost tail calls */
}
if (level > 0 || ci == L->base_ci) status = 0; /* there is no such level */
else if (level < 0) { /* level is of a lost tail call */
status = 1;
ar->i_ci = 0;
}
else {
status = 1;
ar->i_ci = ci - L->base_ci;
}
lua_unlock(L);
return status;
@@ -150,31 +158,19 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
}
static void infoLproto (lua_Debug *ar, Proto *f) {
ar->source = getstr(f->source);
ar->linedefined = f->lineDefined;
ar->what = "Lua";
}
static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
Closure *cl;
if (ttisfunction(func))
cl = clvalue(func);
else {
luaG_runerror(L, "value for `lua_getinfo' is not a function");
cl = NULL; /* to avoid warnings */
}
static void funcinfo (lua_Debug *ar, StkId func) {
Closure *cl = clvalue(func);
if (cl->c.isC) {
ar->source = "=[C]";
ar->linedefined = -1;
ar->what = "C";
}
else
infoLproto(ar, cl->l.p);
else {
ar->source = getstr(cl->l.p->source);
ar->linedefined = cl->l.p->lineDefined;
ar->what = (ar->linedefined == 0) ? "main" : "Lua";
}
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
if (ar->linedefined == 0)
ar->what = "main";
}
@@ -182,41 +178,32 @@ static const char *travglobals (lua_State *L, const TObject *o) {
Table *g = hvalue(gt(L));
int i = sizenode(g);
while (i--) {
Node *n = node(g, i);
if (luaO_rawequalObj(o, val(n)) && ttisstring(key(n)))
return getstr(tsvalue(key(n)));
Node *n = gnode(g, i);
if (luaO_rawequalObj(o, gval(n)) && ttisstring(gkey(n)))
return getstr(tsvalue(gkey(n)));
}
return NULL;
}
static void getname (lua_State *L, const TObject *f, lua_Debug *ar) {
/* try to find a name for given function */
if ((ar->name = travglobals(L, f)) != NULL)
ar->namewhat = "global";
else ar->namewhat = ""; /* not found */
static void info_tailcall (lua_State *L, lua_Debug *ar) {
ar->name = ar->namewhat = "";
ar->what = "tail";
ar->linedefined = ar->currentline = -1;
ar->source = "=(tail call)";
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
ar->nups = 0;
setnilvalue(L->top);
}
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
StkId f;
CallInfo *ci;
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
StkId f, CallInfo *ci) {
int status = 1;
lua_lock(L);
if (*what != '>') { /* function is active? */
ci = L->base_ci + ar->i_ci;
f = ci->base - 1;
}
else {
what++; /* skip the `>' */
ci = NULL;
f = L->top - 1;
}
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(L, ar, f);
funcinfo(ar, f);
break;
}
case 'l': {
@@ -224,25 +211,48 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
break;
}
case 'u': {
ar->nups = (ttisfunction(f)) ? clvalue(f)->c.nupvalues : 0;
ar->nups = clvalue(f)->c.nupvalues;
break;
}
case 'n': {
ar->namewhat = (ci) ? getfuncname(ci, &ar->name) : NULL;
if (ar->namewhat == NULL)
getname(L, f, ar);
if (ar->namewhat == NULL) {
/* try to find a global name */
if ((ar->name = travglobals(L, f)) != NULL)
ar->namewhat = "global";
else ar->namewhat = ""; /* not found */
}
break;
}
case 'f': {
setobj2s(L->top, f);
status = 2;
break;
}
default: status = 0; /* invalid option */
}
}
if (!ci) L->top--; /* pop function */
if (status == 2) incr_top(L);
return status;
}
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
int status = 1;
lua_lock(L);
if (*what == '>') {
StkId f = L->top - 1;
if (!ttisfunction(f))
luaG_runerror(L, "value for `lua_getinfo' is not a function");
status = auxgetinfo(L, what + 1, ar, f, NULL);
L->top--; /* pop function */
}
else if (ar->i_ci != 0) { /* no tail call? */
CallInfo *ci = L->base_ci + ar->i_ci;
lua_assert(ttisfunction(ci->base - 1));
status = auxgetinfo(L, what, ar, ci->base - 1, ci);
}
else
info_tailcall(L, ar);
if (strchr(what, 'f')) incr_top(L);
lua_unlock(L);
return status;
}
@@ -345,7 +355,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
}
case OP_GETUPVAL:
case OP_SETUPVAL: {
check(b < pt->nupvalues);
check(b < pt->nups);
break;
}
case OP_GETGLOBAL:
@@ -404,7 +414,7 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
case OP_CLOSURE: {
int nup;
check(b < pt->sizep);
nup = pt->p[b]->nupvalues;
nup = pt->p[b]->nups;
check(pc + nup < pt->sizecode);
for (; nup>0; nup--) {
OpCode op1 = GET_OPCODE(pt->code[pc+nup]);
@@ -451,8 +461,9 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
lua_assert(pc != -1);
switch (GET_OPCODE(i)) {
case OP_GETGLOBAL: {
lua_assert(ttisstring(&p->k[GETARG_Bx(i)]));
*name = svalue(&p->k[GETARG_Bx(i)]);
int g = GETARG_Bx(i); /* global index */
lua_assert(ttisstring(&p->k[g]));
*name = svalue(&p->k[g]);
return "global";
}
case OP_MOVE: {
@@ -463,11 +474,13 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
break;
}
case OP_GETTABLE: {
*name = kname(p, GETARG_C(i));
int k = GETARG_C(i); /* key index */
*name = kname(p, k);
return "field";
}
case OP_SELF: {
*name = kname(p, GETARG_C(i));
int k = GETARG_C(i); /* key index */
*name = kname(p, k);
return "method";
}
default: break;
@@ -477,18 +490,16 @@ static const char *getobjname (CallInfo *ci, int stackpos, const char **name) {
}
static Instruction getcurrentinstr (CallInfo *ci) {
return (!isLua(ci)) ? (Instruction)(-1) :
ci_func(ci)->l.p->code[currentpc(ci)];
}
static const char *getfuncname (CallInfo *ci, const char **name) {
Instruction i;
if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1))
return NULL; /* calling function is not Lua (or is unknown) */
ci--; /* calling function */
i = getcurrentinstr(ci);
return (GET_OPCODE(i) == OP_CALL ? getobjname(ci, GETARG_A(i), name)
: NULL); /* no useful name found */
i = ci_func(ci)->l.p->code[currentpc(ci)];
if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL)
return getobjname(ci, GETARG_A(i), name);
else
return NULL; /* no useful name can be found */
}
@@ -517,7 +528,7 @@ void luaG_typeerror (lua_State *L, const TObject *o, const char *op) {
void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
if (ttisstring(p1)) p1 = p2;
lua_assert(!ttisstring(p1));
luaG_typeerror(L, p1, "concat");
luaG_typeerror(L, p1, "concatenate");
}

63
ldo.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldo.c,v 1.210 2002/12/04 17:28:27 roberto Exp roberto $
** $Id: ldo.c,v 1.216 2003/02/28 19:45:15 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -31,6 +31,7 @@
/*
** {======================================================
** Error-recovery functions (based on long jumps)
@@ -161,7 +162,10 @@ void luaD_callhook (lua_State *L, int event, int line) {
lua_Debug ar;
ar.event = event;
ar.currentline = line;
ar.i_ci = L->ci - L->base_ci;
if (event == LUA_HOOKTAILRET)
ar.i_ci = 0; /* tail call; no debug information about it */
else
ar.i_ci = L->ci - L->base_ci;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L->ci->top = L->top + LUA_MINSTACK;
L->allowhook = 0; /* cannot call hooks inside a hook */
@@ -187,12 +191,12 @@ static void adjust_varargs (lua_State *L, int nfixargs, StkId base) {
setnilvalue(L->top++);
}
actual -= nfixargs; /* number of extra arguments */
htab = luaH_new(L, 0, 0); /* create `arg' table */
htab = luaH_new(L, actual, 1); /* create `arg' table */
for (i=0; i<actual; i++) /* put extra arguments into `arg' table */
setobj2n(luaH_setnum(L, htab, i+1), L->top - actual + i);
/* store counter in field `n' */
setsvalue(&nname, luaS_newliteral(L, "n"));
setnvalue(luaH_set(L, htab, &nname), actual);
setnvalue(luaH_set(L, htab, &nname), cast(lua_Number, actual));
L->top -= actual; /* remove extra elements from the stack */
sethvalue(L->top, htab);
incr_top(L);
@@ -232,6 +236,7 @@ StkId luaD_precall (lua_State *L, StkId func) {
L->base = L->ci->base = restorestack(L, funcr) + 1;
ci->top = L->base + p->maxstacksize;
ci->u.l.savedpc = p->code; /* starting point */
ci->u.l.tailcalls = 0;
ci->state = CI_SAVEDPC;
while (L->top < ci->top)
setnilvalue(L->top++);
@@ -246,10 +251,8 @@ StkId luaD_precall (lua_State *L, StkId func) {
L->base = L->ci->base = restorestack(L, funcr) + 1;
ci->top = L->top + LUA_MINSTACK;
ci->state = CI_C; /* a C function */
if (L->hookmask & LUA_MASKCALL) {
if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
ci = L->ci; /* previous call may reallocate `ci' */
}
lua_unlock(L);
#ifdef LUA_COMPATUPVALUES
lua_pushupvalues(L);
@@ -261,13 +264,21 @@ StkId luaD_precall (lua_State *L, StkId func) {
}
static StkId callrethooks (lua_State *L, StkId firstResult) {
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
luaD_callhook(L, LUA_HOOKRET, -1);
if (!(L->ci->state & CI_C)) { /* Lua function? */
while (L->ci->u.l.tailcalls--) /* call hook for eventual tail calls */
luaD_callhook(L, LUA_HOOKTAILRET, -1);
}
return restorestack(L, fr);
}
void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
StkId res;
if (L->hookmask & LUA_MASKRET) {
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
luaD_callhook(L, LUA_HOOKRET, -1);
firstResult = restorestack(L, fr);
}
if (L->hookmask & LUA_MASKRET)
firstResult = callrethooks(L, firstResult);
res = L->base - 1; /* res == final position of 1st result */
L->ci--;
L->base = L->ci->base; /* restore base */
@@ -279,7 +290,6 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
while (wanted-- > 0)
setnilvalue(res++);
L->top = res;
luaC_checkGC(L);
}
@@ -291,9 +301,10 @@ void luaD_poscall (lua_State *L, int wanted, StkId firstResult) {
*/
void luaD_call (lua_State *L, StkId func, int nResults) {
StkId firstResult;
lua_assert(!(L->ci->state & CI_CALLING));
if (++L->nCcalls >= LUA_MAXCCALLS) {
if (L->nCcalls == LUA_MAXCCALLS)
luaG_runerror(L, "stack overflow");
luaG_runerror(L, "C stack overflow");
else if (L->nCcalls >= (LUA_MAXCCALLS + (LUA_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
@@ -302,6 +313,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
firstResult = luaV_execute(L); /* call it */
luaD_poscall(L, nResults, firstResult);
L->nCcalls--;
luaC_checkGC(L);
}
@@ -415,10 +427,13 @@ struct SParser { /* data to `f_parser' */
};
static void f_parser (lua_State *L, void *ud) {
struct SParser *p = cast(struct SParser *, ud);
Proto *tf = p->bin ? luaU_undump(L, p->z, &p->buff) :
luaY_parser(L, p->z, &p->buff);
Closure *cl = luaF_newLclosure(L, 0, gt(L));
struct SParser *p;
Proto *tf;
Closure *cl;
luaC_checkGC(L);
p = cast(struct SParser *, ud);
tf = p->bin ? luaU_undump(L, p->z, &p->buff) : luaY_parser(L, p->z, &p->buff);
cl = luaF_newLclosure(L, 0, gt(L));
cl->l.p = tf;
setclvalue(L->top, cl);
incr_top(L);
@@ -427,23 +442,13 @@ static void f_parser (lua_State *L, void *ud) {
int luaD_protectedparser (lua_State *L, ZIO *z, int bin) {
struct SParser p;
lu_mem old_blocks;
int status;
ptrdiff_t oldtopr = savestack(L, L->top); /* save current top */
p.z = z; p.bin = bin;
luaZ_initbuffer(L, &p.buff);
/* before parsing, give a (good) chance to GC */
if (G(L)->nblocks + G(L)->nblocks/4 >= G(L)->GCthreshold)
luaC_collectgarbage(L);
old_blocks = G(L)->nblocks;
status = luaD_rawrunprotected(L, f_parser, &p);
luaZ_freebuffer(L, &p.buff);
if (status == 0) {
/* add new memory to threshold (as it probably will stay) */
lua_assert(G(L)->nblocks >= old_blocks);
G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
}
else { /* error */
if (status != 0) { /* error? */
StkId oldtop = restorestack(L, oldtopr);
seterrorobj(L, status, oldtop);
}

26
ldump.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ldump.c,v 1.1 2002/10/25 21:31:28 roberto Exp roberto $
** $Id: ldump.c,v 1.4 2003/02/11 23:52:12 lhf Exp $
** save bytecodes
** See Copyright Notice in lua.h
*/
@@ -19,13 +19,12 @@
#define DumpLiteral(s,D) DumpBlock("" s,(sizeof(s))-1,D)
typedef struct {
lua_State *L;
lua_State* L;
lua_Chunkwriter write;
void *data;
void* data;
} DumpState;
static void DumpBlock(const void *b, size_t size, DumpState* D)
static void DumpBlock(const void* b, size_t size, DumpState* D)
{
lua_unlock(D->L);
(*D->write)(D->L,b,size,D->data);
@@ -89,6 +88,13 @@ static void DumpLines(const Proto* f, DumpState* D)
DumpVector(f->lineinfo,f->sizelineinfo,sizeof(*f->lineinfo),D);
}
static void DumpUpvalues(const Proto* f, DumpState* D)
{
int i,n=f->sizeupvalues;
DumpInt(n,D);
for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
}
static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
static void DumpConstants(const Proto* f, DumpState* D)
@@ -122,12 +128,13 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
{
DumpString((f->source==p) ? NULL : f->source,D);
DumpInt(f->lineDefined,D);
DumpByte(f->nupvalues,D);
DumpByte(f->nups,D);
DumpByte(f->numparams,D);
DumpByte(f->is_vararg,D);
DumpByte(f->maxstacksize,D);
DumpLocals(f,D);
DumpLines(f,D);
DumpLocals(f,D);
DumpUpvalues(f,D);
DumpConstants(f,D);
DumpCode(f,D);
}
@@ -148,7 +155,10 @@ static void DumpHeader(DumpState* D)
DumpNumber(TEST_NUMBER,D);
}
void luaU_dump(lua_State *L, const Proto* Main, lua_Chunkwriter w, void* data)
/*
** dump function as precompiled chunk
*/
void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data)
{
DumpState D;
D.L=L;

11
lfunc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lfunc.c,v 1.63 2002/11/14 16:15:53 roberto Exp roberto $
** $Id: lfunc.c,v 1.66 2003/02/11 10:46:24 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -35,11 +35,11 @@ Closure *luaF_newCclosure (lua_State *L, int nelems) {
}
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt) {
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
luaC_link(L, valtogco(c), LUA_TFUNCTION);
c->l.isC = 0;
c->l.g = *gt;
c->l.g = *e;
c->l.nupvalues = cast(lu_byte, nelems);
return c;
}
@@ -84,7 +84,9 @@ Proto *luaF_newproto (lua_State *L) {
f->code = NULL;
f->sizecode = 0;
f->sizelineinfo = 0;
f->nupvalues = 0;
f->sizeupvalues = 0;
f->nups = 0;
f->upvalues = NULL;
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
@@ -103,6 +105,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->k, f->sizek, TObject);
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
luaM_freelem(L, f);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lfunc.h,v 1.19 2001/11/29 20:22:22 roberto Exp roberto $
** $Id: lfunc.h,v 1.20 2002/06/20 20:41:46 roberto Exp roberto $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
@@ -13,7 +13,7 @@
Proto *luaF_newproto (lua_State *L);
Closure *luaF_newCclosure (lua_State *L, int nelems);
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt);
Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *e);
UpVal *luaF_findupval (lua_State *L, StkId level);
void luaF_close (lua_State *L, StkId level);
void luaF_freeproto (lua_State *L, Proto *f);

71
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.165 2002/12/02 12:06:10 roberto Exp roberto $
** $Id: lgc.c,v 1.170 2003/03/18 12:50:04 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -27,7 +27,7 @@ typedef struct GCState {
GCObject *wk; /* list of traversed key-weak tables (to be cleared) */
GCObject *wv; /* list of traversed value-weak tables */
GCObject *wkv; /* list of traversed key-value weak tables */
global_State *G;
global_State *g;
} GCState;
@@ -102,7 +102,7 @@ static void reallymarkobject (GCState *st, GCObject *o) {
static void marktmu (GCState *st) {
GCObject *u;
for (u = st->G->tmudata; u; u = u->gch.next) {
for (u = st->g->tmudata; u; u = u->gch.next) {
unmark(u); /* may be marked, if left from previous GC */
reallymarkobject(st, u);
}
@@ -110,7 +110,7 @@ static void marktmu (GCState *st) {
/* move `dead' udata that need finalization to list `tmudata' */
static void separateudata (lua_State *L) {
void luaC_separateudata (lua_State *L) {
GCObject **p = &G(L)->rootudata;
GCObject *curr;
GCObject *collected = NULL; /* to collect udata with gc event */
@@ -138,9 +138,9 @@ static void separateudata (lua_State *L) {
static void removekey (Node *n) {
setnilvalue(val(n)); /* remove corresponding value ... */
if (iscollectable(key(n)))
setttype(key(n), LUA_TNONE); /* dead key; remove it */
setnilvalue(gval(n)); /* remove corresponding value ... */
if (iscollectable(gkey(n)))
setttype(gkey(n), LUA_TNONE); /* dead key; remove it */
}
@@ -150,15 +150,16 @@ static void traversetable (GCState *st, Table *h) {
int weakvalue = 0;
const TObject *mode;
markvalue(st, h->metatable);
lua_assert(h->lsizenode || h->node == st->G->dummynode);
mode = gfasttm(st->G, h->metatable, TM_MODE);
lua_assert(h->lsizenode || h->node == st->g->dummynode);
mode = gfasttm(st->g, h->metatable, TM_MODE);
if (mode && ttisstring(mode)) { /* is there a weak mode? */
weakkey = (strchr(svalue(mode), 'k') != NULL);
weakvalue = (strchr(svalue(mode), 'v') != NULL);
if (weakkey || weakvalue) { /* is really weak? */
GCObject **weaklist;
h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
h->marked |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
(weakvalue << VALUEWEAKBIT));
weaklist = (weakkey && weakvalue) ? &st->wkv :
(weakkey) ? &st->wk :
&st->wv;
@@ -167,17 +168,17 @@ static void traversetable (GCState *st, Table *h) {
}
}
if (!weakvalue) {
i = sizearray(h);
i = h->sizearray;
while (i--)
markobject(st, &h->array[i]);
}
i = sizenode(h);
while (i--) {
Node *n = node(h, i);
if (!ttisnil(val(n))) {
lua_assert(!ttisnil(key(n)));
condmarkobject(st, key(n), !weakkey);
condmarkobject(st, val(n), !weakvalue);
Node *n = gnode(h, i);
if (!ttisnil(gval(n))) {
lua_assert(!ttisnil(gkey(n)));
condmarkobject(st, gkey(n), !weakkey);
condmarkobject(st, gval(n), !weakvalue);
}
}
}
@@ -186,11 +187,13 @@ static void traversetable (GCState *st, Table *h) {
static void traverseproto (GCState *st, Proto *f) {
int i;
stringmark(f->source);
for (i=0; i<f->sizek; i++) {
for (i=0; i<f->sizek; i++) { /* mark literal strings */
if (ttisstring(f->k+i))
stringmark(tsvalue(f->k+i));
}
for (i=0; i<f->sizep; i++)
for (i=0; i<f->sizeupvalues; i++) /* mark upvalue names */
stringmark(f->upvalues[i]);
for (i=0; i<f->sizep; i++) /* mark nested protos */
markvalue(st, f->p[i]);
for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
stringmark(f->locvars[i].varname);
@@ -207,7 +210,7 @@ static void traverseclosure (GCState *st, Closure *cl) {
}
else {
int i;
lua_assert(cl->l.nupvalues == cl->l.p->nupvalues);
lua_assert(cl->l.nupvalues == cl->l.p->nups);
markvalue(st, hvalue(&cl->l.g));
markvalue(st, cl->l.p);
for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
@@ -301,8 +304,8 @@ static void cleartablekeys (GCObject *l) {
int i = sizenode(h);
lua_assert(h->marked & KEYWEAK);
while (i--) {
Node *n = node(h, i);
if (!valismarked(key(n))) /* key was collected? */
Node *n = gnode(h, i);
if (!valismarked(gkey(n))) /* key was collected? */
removekey(n); /* remove entry from table */
}
l = h->gclist;
@@ -316,7 +319,7 @@ static void cleartablekeys (GCObject *l) {
static void cleartablevalues (GCObject *l) {
while (l) {
Table *h = gcotoh(l);
int i = sizearray(h);
int i = h->sizearray;
lua_assert(h->marked & VALUEWEAK);
while (i--) {
TObject *o = &h->array[i];
@@ -325,8 +328,8 @@ static void cleartablevalues (GCObject *l) {
}
i = sizenode(h);
while (i--) {
Node *n = node(h, i);
if (!valismarked(val(n))) /* value was collected? */
Node *n = gnode(h, i);
if (!valismarked(gval(n))) /* value was collected? */
removekey(n); /* remove entry from table */
}
l = h->gclist;
@@ -409,7 +412,7 @@ static void do1gcTM (lua_State *L, Udata *udata) {
}
static void callGCTM (lua_State *L) {
void luaC_callGCTM (lua_State *L) {
lu_byte oldah = L->allowhook;
L->allowhook = 0; /* stop debug hooks during GC tag methods */
L->top++; /* reserve space to keep udata while runs its gc method */
@@ -429,12 +432,6 @@ static void callGCTM (lua_State *L) {
}
void luaC_callallgcTM (lua_State *L) {
separateudata(L);
callGCTM(L); /* call their GC tag methods */
}
void luaC_sweep (lua_State *L, int all) {
if (all) all = 256; /* larger than any mark */
sweeplist(L, &G(L)->rootudata, all);
@@ -445,11 +442,11 @@ void luaC_sweep (lua_State *L, int all) {
/* mark root set */
static void markroot (GCState *st, lua_State *L) {
global_State *G = st->G;
global_State *g = st->g;
markobject(st, defaultmeta(L));
markobject(st, registry(L));
traversestack(st, G->mainthread);
if (L != G->mainthread) /* another thread is running? */
traversestack(st, g->mainthread);
if (L != g->mainthread) /* another thread is running? */
markvalue(st, L); /* cannot collect it */
}
@@ -457,7 +454,7 @@ static void markroot (GCState *st, lua_State *L) {
static void mark (lua_State *L) {
GCState st;
GCObject *wkv;
st.G = G(L);
st.g = G(L);
st.tmark = NULL;
st.wkv = st.wk = st.wv = NULL;
markroot(&st, L);
@@ -467,7 +464,7 @@ static void mark (lua_State *L) {
wkv = st.wkv; /* keys must be cleared after preserving udata */
st.wkv = NULL;
st.wv = NULL;
separateudata(L); /* separate userdata to be preserved */
luaC_separateudata(L); /* separate userdata to be preserved */
marktmu(&st); /* mark `preserved' userdata */
propagatemarks(&st); /* remark, to propagate `preserveness' */
cleartablekeys(wkv);
@@ -483,7 +480,7 @@ void luaC_collectgarbage (lua_State *L) {
mark(L);
luaC_sweep(L, 0);
checkSizes(L);
callGCTM(L);
luaC_callGCTM(L);
}

9
lgc.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.h,v 1.16 2002/08/30 19:09:21 roberto Exp roberto $
** $Id: lgc.h,v 1.18 2003/02/10 17:32:50 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -11,11 +11,12 @@
#include "lobject.h"
#define luaC_checkGC(L) if (G(L)->nblocks >= G(L)->GCthreshold) \
luaC_collectgarbage(L)
#define luaC_checkGC(L) { lua_assert(!(L->ci->state & CI_CALLING)); \
if (G(L)->nblocks >= G(L)->GCthreshold) luaC_collectgarbage(L); }
void luaC_callallgcTM (lua_State *L);
void luaC_separateudata (lua_State *L);
void luaC_callGCTM (lua_State *L);
void luaC_sweep (lua_State *L, int all);
void luaC_collectgarbage (lua_State *L);
void luaC_link (lua_State *L, GCObject *o, lu_byte tt);

109
liolib.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 2.27 2002/12/04 15:27:17 roberto Exp roberto $
** $Id: liolib.c,v 2.38 2003/03/18 12:25:32 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@@ -21,6 +21,36 @@
/*
** by default, gcc does not get `tmpname'
*/
#ifndef USE_TMPNAME
#ifdef __GNUC__
#define USE_TMPNAME 0
#else
#define USE_TMPNAME 1
#endif
#endif
/*
** by default, posix systems get `popen'
*/
#ifndef USE_POPEN
#ifdef _POSIX_C_SOURCE
#if _POSIX_C_SOURCE >= 2
#define USE_POPEN 1
#endif
#endif
#endif
#ifndef USE_POPEN
#define USE_POPEN 0
#endif
/*
** {======================================================
** FILE Operations
@@ -28,12 +58,12 @@
*/
#ifndef USE_POPEN
#if !USE_POPEN
#define pclose(f) (-1)
#endif
#define FILEHANDLE "FileHandle"
#define FILEHANDLE "FILE*"
#define IO_INPUT "_input"
#define IO_OUTPUT "_output"
@@ -57,21 +87,15 @@ static int pushresult (lua_State *L, int i, const char *filename) {
static FILE **topfile (lua_State *L, int findex) {
FILE **f = (FILE **)lua_touserdata(L, findex);
if (f == NULL || !lua_getmetatable(L, findex) ||
!lua_rawequal(L, -1, lua_upvalueindex(1))) {
luaL_argerror(L, findex, "bad file");
}
lua_pop(L, 1);
FILE **f = (FILE **)luaL_checkudata(L, findex, FILEHANDLE);
if (f == NULL) luaL_argerror(L, findex, "bad file");
return f;
}
static int io_type (lua_State *L) {
FILE **f = (FILE **)lua_touserdata(L, 1);
if (f == NULL || !lua_getmetatable(L, 1) ||
!lua_rawequal(L, -1, lua_upvalueindex(1)))
lua_pushnil(L);
FILE **f = (FILE **)luaL_checkudata(L, 1, FILEHANDLE);
if (f == NULL) lua_pushnil(L);
else if (*f == NULL)
lua_pushliteral(L, "closed file");
else
@@ -97,8 +121,7 @@ static FILE *tofile (lua_State *L, int findex) {
static FILE **newfile (lua_State *L) {
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
*pf = NULL; /* file handle is currently `closed' */
lua_pushliteral(L, FILEHANDLE);
lua_rawget(L, LUA_REGISTRYINDEX);
luaL_getmetatable(L, FILEHANDLE);
lua_setmetatable(L, -2);
return pf;
}
@@ -173,7 +196,7 @@ static int io_open (lua_State *L) {
static int io_popen (lua_State *L) {
#ifndef USE_POPEN
#if !USE_POPEN
luaL_error(L, "`popen' not supported");
return 0;
#else
@@ -201,12 +224,7 @@ static FILE *getiofile (lua_State *L, const char *name) {
static int g_iofile (lua_State *L, const char *name, const char *mode) {
if (lua_isnoneornil(L, 1)) {
lua_pushstring(L, name);
lua_rawget(L, lua_upvalueindex(1));
return 1;
}
else {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
lua_pushstring(L, name);
if (filename) {
@@ -222,8 +240,11 @@ static int g_iofile (lua_State *L, const char *name, const char *mode) {
lua_pushvalue(L, 1);
}
lua_rawset(L, lua_upvalueindex(1));
return 0;
}
/* return current value */
lua_pushstring(L, name);
lua_rawget(L, lua_upvalueindex(1));
return 1;
}
@@ -240,10 +261,10 @@ static int io_output (lua_State *L) {
static int io_readline (lua_State *L);
static void aux_lines (lua_State *L, int index, int close) {
static void aux_lines (lua_State *L, int idx, int close) {
lua_pushliteral(L, FILEHANDLE);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushvalue(L, index);
lua_pushvalue(L, idx);
lua_pushboolean(L, close); /* close/not close file when finished */
lua_pushcclosure(L, io_readline, 3);
}
@@ -356,8 +377,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
}
else {
const char *p = lua_tostring(L, n);
if (!p || p[0] != '*')
return luaL_error(L, "invalid `read' option");
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
case 'n': /* number */
success = read_number(L, f);
@@ -370,7 +390,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
success = 1; /* always success */
break;
case 'w': /* word */
return luaL_error(L, "obsolete option `*w'");
return luaL_error(L, "obsolete option `*w' to `read'");
default:
return luaL_argerror(L, n, "invalid format");
}
@@ -492,29 +512,19 @@ static const luaL_reg flib[] = {
{"seek", f_seek},
{"write", f_write},
{"close", io_close},
{"__gc", io_gc},
{"__tostring", io_tostring},
{NULL, NULL}
};
static void createmeta (lua_State *L) {
lua_pushliteral(L, FILEHANDLE);
lua_newtable(L); /* push new metatable for file handles */
/* close files when collected */
lua_pushliteral(L, "__gc");
lua_pushvalue(L, -2); /* push metatable (will be upvalue for `gc' method) */
lua_pushcclosure(L, io_gc, 1);
lua_rawset(L, -3); /* metatable.__gc = io_gc */
lua_pushliteral(L, "__tostring");
lua_pushvalue(L, -2); /* push metatable */
lua_pushcclosure(L, io_tostring, 1);
lua_rawset(L, -3);
luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */
/* file methods */
lua_pushliteral(L, "__index");
lua_pushvalue(L, -2); /* push metatable */
lua_rawset(L, -3); /* metatable.__index = metatable */
lua_pushvalue(L, -1); /* push metatable (will be upvalue for library) */
luaL_openlib(L, NULL, flib, 1);
lua_rawset(L, LUA_REGISTRYINDEX); /* registry.FILEHANDLE = metatable */
luaL_openlib(L, NULL, flib, 0);
}
/* }====================================================== */
@@ -546,11 +556,16 @@ static int io_rename (lua_State *L) {
static int io_tmpname (lua_State *L) {
#if !USE_TMPNAME
luaL_error(L, "`tmpname' not supported");
return 0;
#else
char buff[L_tmpnam];
if (tmpnam(buff) != buff)
return luaL_error(L, "unable to generate a unique filename");
return luaL_error(L, "unable to generate a unique filename in `tmpname'");
lua_pushstring(L, buff);
return 1;
#endif
}
@@ -721,17 +736,15 @@ static const luaL_reg syslib[] = {
LUALIB_API int lua_iolibopen (lua_State *L) {
createmeta(L);
LUALIB_API int luaopen_io (lua_State *L) {
luaL_openlib(L, LUA_OSLIBNAME, syslib, 0);
lua_pushliteral(L, FILEHANDLE);
lua_rawget(L, LUA_REGISTRYINDEX);
createmeta(L);
lua_pushvalue(L, -1);
luaL_openlib(L, LUA_IOLIBNAME, iolib, 1);
/* put predefined file handles into `io' table */
registerfile(L, stdin, "stdin", IO_INPUT);
registerfile(L, stdout, "stdout", IO_OUTPUT);
registerfile(L, stderr, "stderr", NULL);
return 0;
return 1;
}

13
llex.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.c,v 1.116 2002/10/23 19:08:13 roberto Exp roberto $
** $Id: llex.c,v 1.118 2003/02/28 17:19:47 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -59,15 +59,20 @@ void luaX_checklimit (LexState *ls, int val, int limit, const char *msg) {
}
static void luaX_error (LexState *ls, const char *s, const char *token) {
void luaX_errorline (LexState *ls, const char *s, const char *token, int line) {
lua_State *L = ls->L;
char buff[MAXSRC];
luaO_chunkid(buff, getstr(ls->source), MAXSRC);
luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, ls->linenumber, s, token);
luaO_pushfstring(L, "%s:%d: %s near `%s'", buff, line, s, token);
luaD_throw(L, LUA_ERRSYNTAX);
}
static void luaX_error (LexState *ls, const char *s, const char *token) {
luaX_errorline(ls, s, token, ls->linenumber);
}
void luaX_syntaxerror (LexState *ls, const char *msg) {
const char *lasttoken;
switch (ls->t.token) {
@@ -88,7 +93,7 @@ void luaX_syntaxerror (LexState *ls, const char *msg) {
const char *luaX_token2str (LexState *ls, int token) {
if (token < FIRST_RESERVED) {
lua_assert(token == (char)token);
lua_assert(token == (unsigned char)token);
return luaO_pushfstring(ls->L, "%c", token);
}
else

3
llex.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: llex.h,v 1.45 2002/10/08 18:46:08 roberto Exp roberto $
** $Id: llex.h,v 1.46 2002/11/22 16:35:20 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -68,6 +68,7 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source);
int luaX_lex (LexState *LS, SemInfo *seminfo);
void luaX_checklimit (LexState *ls, int val, int limit, const char *msg);
void luaX_syntaxerror (LexState *ls, const char *s);
void luaX_errorline (LexState *ls, const char *s, const char *token, int line);
const char *luaX_token2str (LexState *ls, int token);

View File

@@ -1,5 +1,5 @@
/*
** $Id: llimits.h,v 1.50 2002/11/22 18:01:46 roberto Exp roberto $
** $Id: llimits.h,v 1.51 2002/11/25 17:47:13 roberto Exp roberto $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -49,6 +49,9 @@ typedef int ls_hash;
/* it should be at least as large as size_t */
typedef unsigned long lu_mem;
#define MAX_LUMEM ULONG_MAX
/* an integer big enough to count the number of strings in use */
typedef long ls_nstr;

View File

@@ -1,5 +1,5 @@
/*
** $Id: lmathlib.c,v 1.52 2002/11/14 15:41:38 roberto Exp roberto $
** $Id: lmathlib.c,v 1.55 2003/03/11 12:24:34 roberto Exp roberto $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -233,14 +233,14 @@ static const luaL_reg mathlib[] = {
/*
** Open math library
*/
LUALIB_API int lua_mathlibopen (lua_State *L) {
LUALIB_API int luaopen_math (lua_State *L) {
luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0);
lua_pushliteral(L, "pi");
lua_pushnumber(L, PI);
lua_settable(L, -3);
lua_pushliteral(L, "__pow");
lua_pushcfunction(L, math_pow);
lua_settable(L, LUA_REGISTRYINDEX);
return 0;
lua_settable(L, LUA_GLOBALSINDEX);
return 1;
}

205
loadlib.c Normal file
View File

@@ -0,0 +1,205 @@
/*
** $Id: loadlib.c,v 1.3 2003/04/02 13:09:14 roberto Exp roberto $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
*
* This Lua library exports a single function, called loadlib, which is
* called from Lua as loadlib(lib,init), where lib is the full name of the
* library to be loaded (including the complete path) and init is the name
* of a function to be called after the library is loaded. Typically, this
* function will register other functions, thus making the complete library
* available to Lua. The init function is *not* automatically called by
* loadlib. Instead, loadlib returns the init function as a Lua function
* that the client can call when it thinks is appropriate. In the case of
* errors, loadlib returns nil and two strings describing the error.
* The first string is supplied by the operating system; it should be
* informative and useful for error messages. The second string is "open",
* "init", or "absent" to identify the error and is meant to be used for
* making decisions without having to look into the first string (whose
* format is system-dependent).
*
* This module contains an implementation of loadlib for Unix systems that
* have dlfcn, an implementation for Windows, and a stub for other systems.
* See the list at the end of this file for some links to available
* implementations of dlfcn and interfaces to other native dynamic loaders
* on top of which loadlib could be implemented.
*
*/
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#undef LOADLIB
#ifdef USE_DLOPEN
#define LOADLIB
/*
* This is an implementation of loadlib based on the dlfcn interface.
* The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
* NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
* as an emulation layer on top of native functions.
*/
#include <dlfcn.h>
static int loadlib(lua_State *L)
{
const char *path=luaL_checkstring(L,1);
const char *init=luaL_checkstring(L,2);
void *lib=dlopen(path,RTLD_NOW);
if (lib!=NULL)
{
lua_CFunction f=(lua_CFunction) dlsym(lib,init);
if (f!=NULL)
{
lua_pushlightuserdata(L,lib);
lua_pushcclosure(L,f,1);
return 1;
}
}
/* else return appropriate error messages */
lua_pushnil(L);
lua_pushstring(L,dlerror());
lua_pushstring(L,(lib!=NULL) ? "init" : "open");
if (lib!=NULL) dlclose(lib);
return 3;
}
#endif
/*
** In Windows, default is to use dll; otherwise, default is not to use dll
*/
#ifndef USE_DLL
#ifdef _WIN32
#define USE_DLL 1
#else
#define USE_DLL 0
#endif
#endif
#if USE_DLL
#define LOADLIB
/*
* This is an implementation of loadlib for Windows using native functions.
*/
#include <windows.h>
static void pusherror(lua_State *L)
{
int error=GetLastError();
char buffer[128];
if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
0, error, 0, buffer, sizeof(buffer), 0))
lua_pushstring(L,buffer);
else
lua_pushfstring(L,"system error %d\n",error);
}
static int loadlib(lua_State *L)
{
const char *path=luaL_checkstring(L,1);
const char *init=luaL_checkstring(L,2);
HINSTANCE lib=LoadLibrary(path);
if (lib!=NULL)
{
lua_CFunction f=(lua_CFunction) GetProcAddress(lib,init);
if (f!=NULL)
{
lua_pushlightuserdata(L,lib);
lua_pushcclosure(L,f,1);
return 1;
}
}
lua_pushnil(L);
pusherror(L);
lua_pushstring(L,(lib!=NULL) ? "init" : "open");
if (lib!=NULL) FreeLibrary(lib);
return 3;
}
#endif
#ifndef LOADLIB
/* Fallback for other systems */
/*
** Those systems support dlopen, so they should have defined USE_DLOPEN.
** The default (no)implementation gives them a special error message.
*/
#ifdef linux
#define LOADLIB
#endif
#ifdef sun
#define LOADLIB
#endif
#ifdef sgi
#define LOADLIB
#endif
#ifdef BSD
#define LOADLIB
#endif
#ifdef _WIN32
#define LOADLIB
#endif
#ifdef LOADLIB
#undef LOADLIB
#define LOADLIB "`loadlib' not installed (check your Lua configuration)"
#else
#define LOADLIB "`loadlib' not supported"
#endif
static int loadlib(lua_State *L)
{
lua_pushnil(L);
lua_pushliteral(L,LOADLIB);
lua_pushliteral(L,"absent");
return 3;
}
#endif
LUALIB_API int luaopen_loadlib (lua_State *L)
{
lua_register(L,"loadlib",loadlib);
return 0;
}
/*
* Here are some links to available implementations of dlfcn and
* interfaces to other native dynamic loaders on top of which loadlib
* could be implemented. Please send contributions and corrections to us.
*
* AIX
* Starting with AIX 4.2, dlfcn is included in the base OS.
* There is also an emulation package available.
* http://www.faqs.org/faqs/aix-faq/part4/section-21.html
*
* HPUX
* HPUX 11 has dlfcn. For HPUX 10 use shl_*.
* http://www.geda.seul.org/mailinglist/geda-dev37/msg00094.html
* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
*
* Macintosh, Windows
* http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html
*
* Mac OS X/Darwin
* http://www.opendarwin.org/projects/dlcompat/
*
* GLIB has wrapper code for BeOS, OS2, Unix and Windows
* http://cvs.gnome.org/lxr/source/glib/gmodule/
*
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.c,v 1.93 2002/11/21 15:16:04 roberto Exp roberto $
** $Id: lobject.c,v 1.96 2003/02/18 16:02:56 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -30,6 +30,20 @@
const TObject luaO_nilobject = {LUA_TNIL, {NULL}};
/*
** converts an integer to a "floating point byte", represented as
** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
*/
int luaO_int2fb (unsigned int x) {
int m = 0; /* mantissa */
while (x >= (1<<3)) {
x = (x+1) >> 1;
m++;
}
return (m << 3) | cast(int, x);
}
int luaO_log2 (unsigned int x) {
static const lu_byte log_8[255] = {
0,
@@ -59,19 +73,19 @@ int luaO_log2 (unsigned int x) {
int luaO_rawequalObj (const TObject *t1, const TObject *t2) {
if (ttype(t1) != ttype(t2)) return 0;
if (iscollectable(t1)) return gcvalue(t1) == gcvalue(t2);
else switch (ttype(t1)) {
case LUA_TNIL:
return 1;
case LUA_TNUMBER:
return nvalue(t1) == nvalue(t2);
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
case LUA_TLIGHTUSERDATA:
return pvalue(t1) == pvalue(t2);
case LUA_TNUMBER:
return nvalue(t1) == nvalue(t2);
default:
lua_assert(iscollectable(t1));
return gcvalue(t1) == gcvalue(t2);
}
lua_assert(0);
return 0; /* to avoid warnings */
}
@@ -114,11 +128,11 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
break;
}
case 'd':
setnvalue(L->top, va_arg(argp, int));
setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
incr_top(L);
break;
case 'f':
setnvalue(L->top, va_arg(argp, l_uacNumber));
setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
incr_top(L);
break;
case '%':

View File

@@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 1.154 2002/11/14 11:51:50 roberto Exp roberto $
** $Id: lobject.h,v 1.158 2003/02/18 16:02:56 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -214,7 +214,9 @@ typedef struct Proto {
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines */
struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */
TString *source;
int sizeupvalues;
int sizek; /* size of `k' */
int sizecode;
int sizelineinfo;
@@ -222,7 +224,7 @@ typedef struct Proto {
int sizelocvars;
int lineDefined;
GCObject *gclist;
lu_byte nupvalues;
lu_byte nups; /* number of upvalues */
lu_byte numparams;
lu_byte is_vararg;
lu_byte maxstacksize;
@@ -314,14 +316,14 @@ typedef struct Table {
#define twoto(x) (1<<(x))
#define sizenode(t) (twoto((t)->lsizenode))
#define sizearray(t) ((t)->sizearray)
extern const TObject luaO_nilobject;
int luaO_log2 (unsigned int x);
int luaO_int2fb (unsigned int x);
#define fb2int(x) (((x) & 7) << ((x) >> 3))
int luaO_rawequalObj (const TObject *t1, const TObject *t2);
int luaO_str2d (const char *s, lua_Number *result);

View File

@@ -1,5 +1,5 @@
/*
** $Id: lparser.c,v 1.201 2002/12/06 17:09:00 roberto Exp roberto $
** $Id: lparser.c,v 1.207 2003/02/28 17:19:47 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -179,16 +179,22 @@ static void create_local (LexState *ls, const char *name) {
}
static int indexupvalue (FuncState *fs, expdesc *v) {
static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
int i;
for (i=0; i<fs->f->nupvalues; i++) {
if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info)
Proto *f = fs->f;
for (i=0; i<f->nups; i++) {
if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->info) {
lua_assert(fs->f->upvalues[i] == name);
return i;
}
}
/* new one */
luaX_checklimit(fs->ls, fs->f->nupvalues+1, MAXUPVALUES, "upvalues");
fs->upvalues[fs->f->nupvalues] = *v;
return fs->f->nupvalues++;
luaX_checklimit(fs->ls, f->nups + 1, MAXUPVALUES, "upvalues");
luaM_growvector(fs->L, fs->f->upvalues, f->nups, fs->f->sizeupvalues,
TString *, MAX_INT, "");
fs->f->upvalues[f->nups] = name;
fs->upvalues[f->nups] = *v;
return f->nups++;
}
@@ -226,7 +232,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
var->info = luaK_stringK(fs, n); /* info points to global name */
}
else { /* LOCAL or UPVAL */
var->info = indexupvalue(fs, var);
var->info = indexupvalue(fs, n, var);
var->k = VUPVAL; /* upvalue in this level */
}
}
@@ -234,8 +240,10 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
}
static void singlevar (LexState *ls, expdesc *var, int base) {
singlevaraux(ls->fs, str_checkname(ls), var, base);
static TString *singlevar (LexState *ls, expdesc *var, int base) {
TString *varname = str_checkname(ls);
singlevaraux(ls->fs, varname, var, base);
return varname;
}
@@ -302,7 +310,7 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
MAXARG_Bx, "constant table overflow");
f->p[fs->np++] = func->f;
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
for (i=0; i<func->f->nupvalues; i++) {
for (i=0; i<func->f->nups; i++) {
OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
}
@@ -326,11 +334,8 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->nlocvars = 0;
fs->nactvar = 0;
fs->bl = NULL;
f->code = NULL;
f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */
f->numparams = 0; /* default for main chunk */
f->is_vararg = 0; /* default for main chunk */
}
@@ -350,6 +355,8 @@ static void close_func (LexState *ls) {
f->sizep = fs->np;
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
f->sizelocvars = fs->nlocvars;
luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
f->sizeupvalues = f->nups;
lua_assert(luaG_checkcode(f));
lua_assert(fs->bl == NULL);
ls->fs = fs->prev;
@@ -368,7 +375,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff) {
check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
close_func(&lexstate);
lua_assert(funcstate.prev == NULL);
lua_assert(funcstate.f->nupvalues == 0);
lua_assert(funcstate.f->nups == 0);
lua_assert(lexstate.nestlevel == 0);
return funcstate.f;
}
@@ -510,8 +517,7 @@ static void constructor (LexState *ls, expdesc *t) {
} while (testnext(ls, ',') || testnext(ls, ';'));
check_match(ls, '}', '{', line);
lastlistfield(fs, &cc);
if (cc.na > 0)
SETARG_B(fs->f->code[pc], luaO_log2(cc.na-1)+2); /* set initial table size */
SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
SETARG_C(fs->f->code[pc], luaO_log2(cc.nh)+1); /* set initial table size */
}
@@ -639,12 +645,18 @@ static void prefixexp (LexState *ls, expdesc *v) {
singlevar(ls, v, 1);
return;
}
#ifdef LUA_COMPATUPSYNTAX
case '%': { /* for compatibility only */
TString *varname;
int line = ls->linenumber;
next(ls); /* skip `%' */
singlevar(ls, v, 1);
check_condition(ls, v->k == VUPVAL, "global upvalues are obsolete");
varname = singlevar(ls, v, 1);
if (v->k != VUPVAL)
luaX_errorline(ls, "global upvalues are obsolete",
getstr(varname), line);
return;
}
#endif
default: {
luaX_syntaxerror(ls, "unexpected symbol");
return;
@@ -949,7 +961,7 @@ static void cond (LexState *ls, expdesc *v) {
static void whilestat (LexState *ls, int line) {
/* whilestat -> WHILE cond DO block END */
Instruction codeexp[MAXEXPWHILE + EXTRAEXP];
int lineexp = 0;
int lineexp;
int i;
int sizeexp;
FuncState *fs = ls->fs;

View File

@@ -1,5 +1,5 @@
/*
** $Id: lparser.h,v 1.44 2002/05/14 17:52:22 roberto Exp roberto $
** $Id: lparser.h,v 1.46 2002/12/19 11:11:55 roberto Exp roberto $
** Lua Parser
** See Copyright Notice in lua.h
*/

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.c,v 1.116 2002/11/22 17:16:52 roberto Exp roberto $
** $Id: lstate.c,v 1.122 2003/03/18 12:50:04 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -100,21 +100,21 @@ static void f_luaopen (lua_State *L, void *ud) {
setnilvalue(defaultmeta(L));
setnilvalue(registry(L));
luaZ_initbuffer(L, &g->buff);
g->panic = &default_panic;
g->panic = default_panic;
g->rootgc = NULL;
g->rootudata = NULL;
g->tmudata = NULL;
setnilvalue(key(g->dummynode));
setnilvalue(val(g->dummynode));
setnilvalue(gkey(g->dummynode));
setnilvalue(gval(g->dummynode));
g->dummynode->next = NULL;
g->nblocks = sizeof(lua_State) + sizeof(global_State);
stack_init(L, L); /* init stack */
/* create default meta table with a dummy table, and then close the loop */
defaultmeta(L)->tt = LUA_TTABLE;
sethvalue(defaultmeta(L), luaH_new(L, 0, 4));
sethvalue(defaultmeta(L), luaH_new(L, 0, 0));
hvalue(defaultmeta(L))->metatable = hvalue(defaultmeta(L));
sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
sethvalue(registry(L), luaH_new(L, 0, 0)); /* registry */
sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
@@ -182,6 +182,8 @@ LUA_API lua_State *lua_open (void) {
lua_State *L = mallocstate(NULL);
if (L) { /* allocation OK? */
L->tt = LUA_TTHREAD;
L->marked = 0;
L->next = L->gclist = NULL;
preinit_state(L);
L->l_G = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
@@ -195,10 +197,23 @@ LUA_API lua_State *lua_open (void) {
}
static void callallgcTM (lua_State *L, void *ud) {
UNUSED(ud);
luaC_callGCTM(L); /* call GC metamethods for all udata */
}
LUA_API void lua_close (lua_State *L) {
lua_lock(L);
L = G(L)->mainthread; /* only the main thread can be closed */
luaC_callallgcTM(L); /* call GC tag methods for all udata */
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_separateudata(L); /* separate udata that have GC metamethods */
L->errfunc = 0; /* no error function during GC metamethods */
do { /* repeat until no more errors */
L->ci = L->base_ci;
L->base = L->top = L->ci->base;
L->nCcalls = 0;
} while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
lua_assert(G(L)->tmudata == NULL);
close_state(L);
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstate.h,v 1.107 2002/11/22 18:01:46 roberto Exp roberto $
** $Id: lstate.h,v 1.108 2002/11/25 17:47:13 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -80,6 +80,7 @@ typedef struct CallInfo {
struct { /* for Lua functions */
const Instruction *savedpc;
const Instruction **pc; /* points to `pc' variable in `luaV_execute' */
int tailcalls; /* number of tail calls lost under this entry */
} l;
struct { /* for C functions */
int dummy; /* just to avoid an empty struct */

View File

@@ -1,5 +1,5 @@
/*
** $Id: lstrlib.c,v 1.91 2002/11/25 17:33:33 roberto Exp roberto $
** $Id: lstrlib.c,v 1.97 2003/03/19 21:16:12 roberto Exp roberto $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
@@ -31,7 +31,7 @@ typedef long sint32; /* a signed version for size_t */
static int str_len (lua_State *L) {
size_t l;
luaL_checklstring(L, 1, &l);
lua_pushnumber(L, l);
lua_pushnumber(L, (lua_Number)l);
return 1;
}
@@ -48,7 +48,7 @@ static int str_sub (lua_State *L) {
sint32 start = posrelat(luaL_checklong(L, 2), l);
sint32 end = posrelat(luaL_optlong(L, 3, -1), l);
if (start < 1) start = 1;
if (end > (sint32)l) end = l;
if (end > (sint32)l) end = (sint32)l;
if (start <= end)
lua_pushlstring(L, s+start-1, end-start+1);
else lua_pushliteral(L, "");
@@ -98,7 +98,8 @@ static int str_byte (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
sint32 pos = posrelat(luaL_optlong(L, 2, 1), l);
luaL_argcheck(L, 0 < pos && (size_t)(pos) <= l, 2, "out of range");
if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */
return 0; /* no answer */
lua_pushnumber(L, uchar(s[pos-1]));
return 1;
}
@@ -451,7 +452,7 @@ static void push_onecapture (MatchState *ms, int i) {
int l = ms->capture[i].len;
if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
if (l == CAP_POSITION)
lua_pushnumber(ms->L, ms->capture[i].init - ms->src_init + 1);
lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1));
else
lua_pushlstring(ms->L, ms->capture[i].init, l);
}
@@ -477,14 +478,15 @@ static int str_find (lua_State *L) {
const char *s = luaL_checklstring(L, 1, &l1);
const char *p = luaL_checklstring(L, 2, &l2);
sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1;
luaL_argcheck(L, 0 <= init && (size_t)(init) <= l1, 3, "out of range");
if (init < 0) init = 0;
else if ((size_t)(init) > l1) init = (sint32)l1;
if (lua_toboolean(L, 4) || /* explicit request? */
strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */
/* do a plain search */
const char *s2 = lmemfind(s+init, l1-init, p, l2);
if (s2) {
lua_pushnumber(L, s2-s+1);
lua_pushnumber(L, s2-s+l2);
lua_pushnumber(L, (lua_Number)(s2-s+1));
lua_pushnumber(L, (lua_Number)(s2-s+l2));
return 2;
}
}
@@ -499,8 +501,8 @@ static int str_find (lua_State *L) {
const char *res;
ms.level = 0;
if ((res=match(&ms, s1, p)) != NULL) {
lua_pushnumber(L, s1-s+1); /* start */
lua_pushnumber(L, res-s); /* end */
lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */
lua_pushnumber(L, (lua_Number)(res-s)); /* end */
return push_captures(&ms, NULL, 0) + 2;
}
} while (s1++<ms.src_end && !anchor);
@@ -527,7 +529,7 @@ static int gfind_aux (lua_State *L) {
if ((e = match(&ms, src, p)) != NULL) {
int newstart = e-s;
if (e == src) newstart++; /* empty match? go at least one position */
lua_pushnumber(L, newstart);
lua_pushnumber(L, (lua_Number)newstart);
lua_replace(L, lua_upvalueindex(3));
return push_captures(&ms, src, e);
}
@@ -614,7 +616,7 @@ static int str_gsub (lua_State *L) {
}
luaL_addlstring(&b, src, ms.src_end-src);
luaL_pushresult(&b);
lua_pushnumber(L, n); /* number of substitutions */
lua_pushnumber(L, (lua_Number)n); /* number of substitutions */
return 2;
}
@@ -693,7 +695,7 @@ static int str_format (lua_State *L) {
char buff[MAX_ITEM]; /* to store the formatted item */
int hasprecision = 0;
if (isdigit(uchar(*strfrmt)) && *(strfrmt+1) == '$')
return luaL_error(L, "obsolete `format' option (d$)");
return luaL_error(L, "obsolete option (d$) to `format'");
arg++;
strfrmt = scanformat(L, strfrmt, form, &hasprecision);
switch (*strfrmt++) {
@@ -730,7 +732,7 @@ static int str_format (lua_State *L) {
}
}
default: { /* also treat cases `pnLlh' */
return luaL_error(L, "invalid option in `format'");
return luaL_error(L, "invalid option to `format'");
}
}
luaL_addlstring(&b, buff, strlen(buff));
@@ -761,8 +763,8 @@ static const luaL_reg strlib[] = {
/*
** Open string library
*/
LUALIB_API int lua_strlibopen (lua_State *L) {
LUALIB_API int luaopen_string (lua_State *L) {
luaL_openlib(L, LUA_STRLIBNAME, strlib, 0);
return 0;
return 1;
}

143
ltable.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.c,v 1.125 2002/12/02 12:06:10 roberto Exp roberto $
** $Id: ltable.c,v 1.131 2003/03/24 14:18:42 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -21,6 +21,7 @@
** performance penalties.
*/
#include <string.h>
#define ltable_c
@@ -54,17 +55,41 @@
#endif
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)
#define hashnum(t,n) \
(node(t, lmod(cast(lu_hash, cast(ls_hash, n)), sizenode(t))))
#define hashstr(t,str) (node(t, lmod((str)->tsv.hash, sizenode(t))))
#define hashboolean(t,p) (node(t, lmod(p, sizenode(t))))
/*
** avoid modulus by power of 2 for pointers, as they tend to have many
** 2 factors.
** for some types, it is better to avoid modulus by power of 2, as
** they tend to have many 2 factors.
*/
#define hashpointer(t,p) (node(t, (IntPoint(p) % ((sizenode(t)-1)|1))))
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
#define hashpointer(t,p) hashmod(t, IntPoint(p))
/*
** number of ints inside a lua_Number
*/
#define numints cast(int, sizeof(lua_Number)/sizeof(int))
/*
** hash for lua_Numbers
*/
static Node *hashnum (const Table *t, lua_Number n) {
unsigned int a[numints];
int i;
n += 1; /* normalize number (avoid -0) */
lua_assert(sizeof(a) <= sizeof(n));
memcpy(a, &n, sizeof(a));
for (i = 1; i < numints; i++) a[0] += a[i];
return hashmod(t, cast(lu_hash, a[0]));
}
/*
@@ -73,11 +98,8 @@
*/
Node *luaH_mainposition (const Table *t, const TObject *key) {
switch (ttype(key)) {
case LUA_TNUMBER: {
int ikey;
lua_number2int(ikey, nvalue(key));
return hashnum(t, ikey);
}
case LUA_TNUMBER:
return hashnum(t, nvalue(key));
case LUA_TSTRING:
return hashstr(t, tsvalue(key));
case LUA_TBOOLEAN:
@@ -122,7 +144,7 @@ static int luaH_index (lua_State *L, Table *t, StkId key) {
if (v == &luaO_nilobject)
luaG_runerror(L, "invalid key for `next'");
i = cast(int, (cast(const lu_byte *, v) -
cast(const lu_byte *, val(node(t, 0)))) / sizeof(Node));
cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node));
return i + t->sizearray; /* hash elements are numbered after array ones */
}
}
@@ -132,15 +154,15 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
int i = luaH_index(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setnvalue(key, i+1);
setnvalue(key, cast(lua_Number, i+1));
setobj2s(key+1, &t->array[i]);
return 1;
}
}
for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
if (!ttisnil(val(node(t, i)))) { /* a non-nil value? */
setobj2s(key, key(node(t, i)));
setobj2s(key+1, val(node(t, i)));
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
setobj2s(key, gkey(gnode(t, i)));
setobj2s(key+1, gval(gnode(t, i)));
return 1;
}
}
@@ -160,7 +182,7 @@ static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
int a = nums[0]; /* number of elements smaller than 2^i */
int na = a; /* number of elements to go to array part */
int n = (na == 0) ? -1 : 0; /* (log of) optimal size for array part */
for (i = 1; i <= MAXBITS && *narray >= twoto(i-1); i++) {
for (i = 1; a < *narray && *narray >= twoto(i-1); i++) {
if (nums[i] > 0) {
a += nums[i];
if (a >= twoto(i-1)) { /* more than half elements in use? */
@@ -178,27 +200,31 @@ static void computesizes (int nums[], int ntotal, int *narray, int *nhash) {
static void numuse (const Table *t, int *narray, int *nhash) {
int nums[MAXBITS+1];
int i;
int i, lg;
int totaluse = 0;
for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* init `nums' */
/* count elements in array part */
i = luaO_log2(t->sizearray) + 1; /* number of `slices' */
while (i--) { /* for each slice [2^(i-1) to 2^i) */
int to = twoto(i);
int from = to/2;
if (to > t->sizearray) to = t->sizearray;
for (; from < to; from++)
if (!ttisnil(&t->array[from])) {
nums[i]++;
for (i=0, lg=0; lg<=MAXBITS; lg++) { /* for each slice [2^(lg-1) to 2^lg) */
int ttlg = twoto(lg); /* 2^lg */
if (ttlg > t->sizearray) {
ttlg = t->sizearray;
if (i >= ttlg) break;
}
nums[lg] = 0;
for (; i<ttlg; i++) {
if (!ttisnil(&t->array[i])) {
nums[lg]++;
totaluse++;
}
}
}
for (; lg<=MAXBITS; lg++) nums[lg] = 0; /* reset other counts */
*narray = totaluse; /* all previous uses were in array part */
/* count elements in hash part */
i = sizenode(t);
while (i--) {
if (!ttisnil(val(&t->node[i]))) {
int k = arrayindex(key(&t->node[i]));
Node *n = &t->node[i];
if (!ttisnil(gval(n))) {
int k = arrayindex(gkey(n));
if (k >= 0) { /* is `key' an appropriate array index? */
nums[luaO_log2(k-1)+1]++; /* count as such */
(*narray)++;
@@ -226,20 +252,20 @@ static void setnodevector (lua_State *L, Table *t, int lsize) {
luaG_runerror(L, "table overflow");
if (lsize == 0) { /* no elements to hash part? */
t->node = G(L)->dummynode; /* use common `dummynode' */
lua_assert(ttisnil(key(t->node))); /* assert invariants: */
lua_assert(ttisnil(val(t->node)));
lua_assert(ttisnil(gkey(t->node))); /* assert invariants: */
lua_assert(ttisnil(gval(t->node)));
lua_assert(t->node->next == NULL); /* (`dummynode' must be empty) */
}
else {
t->node = luaM_newvector(L, size, Node);
for (i=0; i<size; i++) {
t->node[i].next = NULL;
setnilvalue(key(node(t, i)));
setnilvalue(val(node(t, i)));
setnilvalue(gkey(gnode(t, i)));
setnilvalue(gval(gnode(t, i)));
}
}
t->lsizenode = cast(lu_byte, lsize);
t->firstfree = node(t, size-1); /* first free position to be used */
t->firstfree = gnode(t, size-1); /* first free position to be used */
}
@@ -255,8 +281,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
lua_assert(t->node == G(L)->dummynode);
temp[0] = t->node[0]; /* copy it to `temp' */
nold = temp;
setnilvalue(key(G(L)->dummynode)); /* restate invariant */
setnilvalue(val(G(L)->dummynode));
setnilvalue(gkey(G(L)->dummynode)); /* restate invariant */
setnilvalue(gval(G(L)->dummynode));
lua_assert(G(L)->dummynode->next == NULL);
}
if (nasize > oldasize) /* array part must grow? */
@@ -277,8 +303,8 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
/* re-insert elements in hash part */
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
Node *old = nold+i;
if (!ttisnil(val(old)))
setobjt2t(luaH_set(L, t, key(old)), val(old));
if (!ttisnil(gval(old)))
setobjt2t(luaH_set(L, t, gkey(old)), gval(old));
}
if (oldhsize)
luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
@@ -328,7 +354,7 @@ void luaH_free (lua_State *L, Table *t) {
** (because gc can call `remove' during a table traversal)
*/
void luaH_remove (Table *t, Node *e) {
Node *mp = luaH_mainposition(t, key(e));
Node *mp = luaH_mainposition(t, gkey(e));
if (e != mp) { /* element not in its main position? */
while (mp->next != e) mp = mp->next; /* find previous */
mp->next = e->next; /* remove `e' from its list */
@@ -336,8 +362,8 @@ void luaH_remove (Table *t, Node *e) {
else {
if (e->next != NULL) ??
}
lua_assert(ttisnil(val(node)));
setnilvalue(key(e)); /* clear node `e' */
lua_assert(ttisnil(gval(node)));
setnilvalue(gkey(e)); /* clear node `e' */
e->next = NULL;
}
#endif
@@ -353,8 +379,8 @@ void luaH_remove (Table *t, Node *e) {
static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
TObject *val;
Node *mp = luaH_mainposition(t, key);
if (!ttisnil(val(mp))) { /* main position is not free? */
Node *othern = luaH_mainposition(t, key(mp)); /* `mp' of colliding node */
if (!ttisnil(gval(mp))) { /* main position is not free? */
Node *othern = luaH_mainposition(t, gkey(mp)); /* `mp' of colliding node */
Node *n = t->firstfree; /* get a free place */
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
@@ -362,7 +388,7 @@ static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
othern->next = n; /* redo the chain with `n' in place of `mp' */
*n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
mp->next = NULL; /* now `mp' is free */
setnilvalue(val(mp));
setnilvalue(gval(mp));
}
else { /* colliding node is in its own main position */
/* new node will go into free position */
@@ -371,16 +397,16 @@ static TObject *newkey (lua_State *L, Table *t, const TObject *key) {
mp = n;
}
}
setobj2t(key(mp), key); /* write barrier */
lua_assert(ttisnil(val(mp)));
setobj2t(gkey(mp), key); /* write barrier */
lua_assert(ttisnil(gval(mp)));
for (;;) { /* correct `firstfree' */
if (ttisnil(key(t->firstfree)))
return val(mp); /* OK; table still has a free place */
if (ttisnil(gkey(t->firstfree)))
return gval(mp); /* OK; table still has a free place */
else if (t->firstfree == t->node) break; /* cannot decrement from here */
else (t->firstfree)--;
}
/* no more free places; must create one */
setbvalue(val(mp), 0); /* avoid new key being removed */
setbvalue(gval(mp), 0); /* avoid new key being removed */
rehash(L, t); /* grow table */
val = cast(TObject *, luaH_get(t, key)); /* get new position */
lua_assert(ttisboolean(val));
@@ -397,7 +423,7 @@ static const TObject *luaH_getany (Table *t, const TObject *key) {
else {
Node *n = luaH_mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key(n), key)) return val(n); /* that's it */
if (luaO_rawequalObj(gkey(n), key)) return gval(n); /* that's it */
else n = n->next;
} while (n);
return &luaO_nilobject;
@@ -412,10 +438,11 @@ const TObject *luaH_getnum (Table *t, int key) {
if (1 <= key && key <= t->sizearray)
return &t->array[key-1];
else {
Node *n = hashnum(t, key);
lua_Number nk = cast(lua_Number, key);
Node *n = hashnum(t, nk);
do { /* check whether `key' is somewhere in the chain */
if (ttisnumber(key(n)) && nvalue(key(n)) == (lua_Number)key)
return val(n); /* that's it */
if (ttisnumber(gkey(n)) && nvalue(gkey(n)) == nk)
return gval(n); /* that's it */
else n = n->next;
} while (n);
return &luaO_nilobject;
@@ -429,8 +456,8 @@ const TObject *luaH_getnum (Table *t, int key) {
const TObject *luaH_getstr (Table *t, TString *key) {
Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */
if (ttisstring(key(n)) && tsvalue(key(n)) == key)
return val(n); /* that's it */
if (ttisstring(gkey(n)) && tsvalue(gkey(n)) == key)
return gval(n); /* that's it */
else n = n->next;
} while (n);
return &luaO_nilobject;
@@ -475,7 +502,7 @@ TObject *luaH_setnum (lua_State *L, Table *t, int key) {
return cast(TObject *, p);
else {
TObject k;
setnvalue(&k, key);
setnvalue(&k, cast(lua_Number, key));
return newkey(L, t, &k);
}
}

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltable.h,v 1.42 2002/05/27 20:35:40 roberto Exp roberto $
** $Id: ltable.h,v 1.43 2002/11/07 16:03:33 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -10,9 +10,9 @@
#include "lobject.h"
#define node(t,i) (&(t)->node[i])
#define key(n) (&(n)->i_key)
#define val(n) (&(n)->i_val)
#define gnode(t,i) (&(t)->node[i])
#define gkey(n) (&(n)->i_key)
#define gval(n) (&(n)->i_val)
const TObject *luaH_getnum (Table *t, int key);

View File

@@ -1,5 +1,5 @@
/*
** $Id: ltablib.c,v 1.16 2002/11/14 15:41:38 roberto Exp roberto $
** $Id: ltablib.c,v 1.20 2003/03/11 12:24:34 roberto Exp roberto $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
@@ -15,52 +15,7 @@
#include "lualib.h"
static int checkint (lua_State *L) {
int n = (int)lua_tonumber(L, -1);
if (n == 0 && !lua_isnumber(L, -1)) n = -1;
lua_pop(L, 1);
return n;
}
static void aux_setn (lua_State *L, int t, int n) {
lua_pushliteral(L, "n");
lua_rawget(L, t);
if (checkint(L) >= 0) {
lua_pushliteral(L, "n"); /* use it */
lua_pushnumber(L, n);
lua_rawset(L, t);
}
else { /* use N */
lua_pushvalue(L, t);
lua_pushnumber(L, n);
lua_rawset(L, lua_upvalueindex(1)); /* N[t] = n */
}
}
static int aux_getn (lua_State *L, int t) {
int n;
luaL_checktype(L, t, LUA_TTABLE);
lua_pushliteral(L, "n"); /* try t.n */
lua_rawget(L, t);
if ((n = checkint(L)) >= 0) return n;
lua_pushvalue(L, t); /* try N[t] */
lua_rawget(L, lua_upvalueindex(1));
if ((n = checkint(L)) >= 0) return n;
else { /* must count elements */
n = 0;
for (;;) {
lua_rawgeti(L, t, ++n);
if (lua_isnil(L, -1)) break;
lua_pop(L, 1);
}
lua_pop(L, 1);
aux_setn(L, t, n - 1);
return n - 1;
}
}
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
static int luaB_foreachi (lua_State *L) {
@@ -69,7 +24,7 @@ static int luaB_foreachi (lua_State *L) {
luaL_checktype(L, 2, LUA_TFUNCTION);
for (i=1; i<=n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushnumber(L, i); /* 1st argument */
lua_pushnumber(L, (lua_Number)i); /* 1st argument */
lua_rawgeti(L, 1, i); /* 2nd argument */
lua_call(L, 2, 1);
if (!lua_isnil(L, -1))
@@ -99,14 +54,14 @@ static int luaB_foreach (lua_State *L) {
static int luaB_getn (lua_State *L) {
lua_pushnumber(L, aux_getn(L, 1));
lua_pushnumber(L, (lua_Number)aux_getn(L, 1));
return 1;
}
static int luaB_setn (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
aux_setn(L, 1, luaL_checkint(L, 2));
luaL_setn(L, 1, luaL_checkint(L, 2));
return 0;
}
@@ -122,7 +77,7 @@ static int luaB_tinsert (lua_State *L) {
if (pos > n) n = pos; /* `grow' array if necessary */
v = 3; /* function may be called with more than 3 args */
}
aux_setn(L, 1, n); /* new size */
luaL_setn(L, 1, n); /* new size */
while (--n >= pos) { /* move up elements */
lua_rawgeti(L, 1, n);
lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */
@@ -137,7 +92,7 @@ static int luaB_tremove (lua_State *L) {
int n = aux_getn(L, 1);
int pos = luaL_optint(L, 2, n);
if (n <= 0) return 0; /* table is `empty' */
aux_setn(L, 1, n-1); /* t.n = n-1 */
luaL_setn(L, 1, n-1); /* t.n = n-1 */
lua_rawgeti(L, 1, pos); /* result = t[pos] */
for ( ;pos<n; pos++) {
lua_rawgeti(L, 1, pos+1);
@@ -156,7 +111,7 @@ static int str_concat (lua_State *L) {
int i = luaL_optint(L, 3, 1);
int n = luaL_optint(L, 4, 0);
luaL_checktype(L, 1, LUA_TTABLE);
if (n == 0) n = aux_getn(L, 1);
if (n == 0) n = luaL_getn(L, 1);
luaL_buffinit(L, &b);
for (; i <= n; i++) {
lua_rawgeti(L, 1, i);
@@ -288,14 +243,8 @@ static const luaL_reg tab_funcs[] = {
};
LUALIB_API int lua_tablibopen (lua_State *L) {
lua_newtable(L); /* create N (table to store num. elements in tables) */
lua_pushvalue(L, -1); /* `N' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, "__mode");
lua_pushliteral(L, "k");
lua_rawset(L, -3); /* metatable(N).__mode = "k" */
luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 1);
return 0;
LUALIB_API int luaopen_table (lua_State *L) {
luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
return 1;
}

179
ltests.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 1.147 2002/12/04 17:29:05 roberto Exp roberto $
** $Id: ltests.c,v 1.157 2003/04/03 13:35:34 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -36,17 +36,20 @@
#ifdef LUA_DEBUG
#define lua_pushintegral(L,i) lua_pushnumber(L, cast(lua_Number, (i)))
static lua_State *lua_state = NULL;
int islocked = 0;
#define index(L,k) (L->ci->base+(k) - 1)
#define func_at(L,k) (L->ci->base+(k) - 1)
static void setnameval (lua_State *L, const char *name, int val) {
lua_pushstring(L, name);
lua_pushnumber(L, val);
lua_pushintegral(L, val);
lua_settable(L, -3);
}
@@ -190,13 +193,13 @@ static int listcode (lua_State *L) {
Proto *p;
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
1, "Lua function expected");
p = clvalue(index(L, 1))->l.p;
p = clvalue(func_at(L, 1))->l.p;
lua_newtable(L);
setnameval(L, "maxstack", p->maxstacksize);
setnameval(L, "numparams", p->numparams);
for (pc=0; pc<p->sizecode; pc++) {
char buff[100];
lua_pushnumber(L, pc+1);
lua_pushintegral(L, pc+1);
lua_pushstring(L, buildop(p, pc, buff));
lua_settable(L, -3);
}
@@ -209,10 +212,10 @@ static int listk (lua_State *L) {
int i;
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
1, "Lua function expected");
p = clvalue(index(L, 1))->l.p;
p = clvalue(func_at(L, 1))->l.p;
lua_newtable(L);
for (i=0; i<p->sizek; i++) {
lua_pushnumber(L, i+1);
lua_pushintegral(L, i+1);
luaA_pushobject(L, p->k+i);
lua_settable(L, -3);
}
@@ -227,7 +230,7 @@ static int listlocals (lua_State *L) {
const char *name;
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
1, "Lua function expected");
p = clvalue(index(L, 1))->l.p;
p = clvalue(func_at(L, 1))->l.p;
while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
lua_pushstring(L, name);
return i-1;
@@ -252,9 +255,9 @@ static int get_limits (lua_State *L) {
static int mem_query (lua_State *L) {
if (lua_isnone(L, 1)) {
lua_pushnumber(L, memdebug_total);
lua_pushnumber(L, memdebug_numblocks);
lua_pushnumber(L, memdebug_maxmem);
lua_pushintegral(L, memdebug_total);
lua_pushintegral(L, memdebug_numblocks);
lua_pushintegral(L, memdebug_maxmem);
return 3;
}
else {
@@ -267,14 +270,14 @@ static int mem_query (lua_State *L) {
static int hash_query (lua_State *L) {
if (lua_isnone(L, 2)) {
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
lua_pushnumber(L, tsvalue(index(L, 1))->tsv.hash);
lua_pushintegral(L, tsvalue(func_at(L, 1))->tsv.hash);
}
else {
TObject *o = index(L, 1);
TObject *o = func_at(L, 1);
Table *t;
luaL_checktype(L, 2, LUA_TTABLE);
t = hvalue(index(L, 2));
lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
t = hvalue(func_at(L, 2));
lua_pushintegral(L, luaH_mainposition(t, o) - t->node);
}
return 1;
}
@@ -282,11 +285,11 @@ static int hash_query (lua_State *L) {
static int stacklevel (lua_State *L) {
unsigned long a = 0;
lua_pushnumber(L, (int)(L->top - L->stack));
lua_pushnumber(L, (int)(L->stack_last - L->stack));
lua_pushnumber(L, (int)(L->ci - L->base_ci));
lua_pushnumber(L, (int)(L->end_ci - L->base_ci));
lua_pushnumber(L, (unsigned long)&a);
lua_pushintegral(L, (int)(L->top - L->stack));
lua_pushintegral(L, (int)(L->stack_last - L->stack));
lua_pushintegral(L, (int)(L->ci - L->base_ci));
lua_pushintegral(L, (int)(L->end_ci - L->base_ci));
lua_pushintegral(L, (unsigned long)&a);
return 5;
}
@@ -295,28 +298,28 @@ static int table_query (lua_State *L) {
const Table *t;
int i = luaL_optint(L, 2, -1);
luaL_checktype(L, 1, LUA_TTABLE);
t = hvalue(index(L, 1));
t = hvalue(func_at(L, 1));
if (i == -1) {
lua_pushnumber(L, t->sizearray);
lua_pushnumber(L, sizenode(t));
lua_pushnumber(L, t->firstfree - t->node);
lua_pushintegral(L, t->sizearray);
lua_pushintegral(L, sizenode(t));
lua_pushintegral(L, t->firstfree - t->node);
}
else if (i < t->sizearray) {
lua_pushnumber(L, i);
lua_pushintegral(L, i);
luaA_pushobject(L, &t->array[i]);
lua_pushnil(L);
}
else if ((i -= t->sizearray) < sizenode(t)) {
if (!ttisnil(val(node(t, i))) ||
ttisnil(key(node(t, i))) ||
ttisnumber(key(node(t, i)))) {
luaA_pushobject(L, key(node(t, i)));
if (!ttisnil(gval(gnode(t, i))) ||
ttisnil(gkey(gnode(t, i))) ||
ttisnumber(gkey(gnode(t, i)))) {
luaA_pushobject(L, gkey(gnode(t, i)));
}
else
lua_pushstring(L, "<undef>");
luaA_pushobject(L, val(&t->node[i]));
luaA_pushobject(L, gval(gnode(t, i)));
if (t->node[i].next)
lua_pushnumber(L, t->node[i].next - t->node);
lua_pushintegral(L, t->node[i].next - t->node);
else
lua_pushnil(L);
}
@@ -328,8 +331,8 @@ static int string_query (lua_State *L) {
stringtable *tb = &G(L)->strt;
int s = luaL_optint(L, 2, 0) - 1;
if (s==-1) {
lua_pushnumber(L ,tb->nuse);
lua_pushnumber(L ,tb->size);
lua_pushintegral(L ,tb->nuse);
lua_pushintegral(L ,tb->size);
return 2;
}
else if (s < tb->size) {
@@ -351,7 +354,7 @@ static int tref (lua_State *L) {
int lock = luaL_optint(L, 2, 1);
luaL_checkany(L, 1);
lua_pushvalue(L, 1);
lua_pushnumber(L, lua_ref(L, lock));
lua_pushintegral(L, lua_ref(L, lock));
assert(lua_gettop(L) == level+1); /* +1 for result */
return 1;
}
@@ -384,6 +387,24 @@ static int metatable (lua_State *L) {
return 1;
}
static int upvalue (lua_State *L) {
int n = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION);
if (lua_isnone(L, 3)) {
const char *name = lua_getupvalue(L, 1, n);
if (name == NULL) return 0;
lua_pushstring(L, name);
return 2;
}
else {
const char *name = lua_setupvalue(L, 1, n);
lua_pushstring(L, name);
return 1;
}
}
static int newuserdata (lua_State *L) {
size_t size = luaL_checkint(L, 1);
char *p = cast(char *, lua_newuserdata(L, size));
@@ -399,7 +420,7 @@ static int pushuserdata (lua_State *L) {
static int udataval (lua_State *L) {
lua_pushnumber(L, cast(int, lua_touserdata(L, 1)));
lua_pushintegral(L, cast(int, lua_touserdata(L, 1)));
return 1;
}
@@ -411,7 +432,7 @@ static int doonnewstack (lua_State *L) {
int status = luaL_loadbuffer(L1, s, l, s);
if (status == 0)
status = lua_pcall(L1, 0, 0, 0);
lua_pushnumber(L, status);
lua_pushintegral(L, status);
return 1;
}
@@ -432,20 +453,28 @@ static int newstate (lua_State *L) {
lua_State *L1 = lua_open();
if (L1) {
lua_userstateopen(L1); /* init lock */
lua_pushnumber(L, (unsigned long)L1);
lua_pushintegral(L, (unsigned long)L1);
}
else
lua_pushnil(L);
return 1;
}
static int loadlib (lua_State *L) {
lua_State *L1 = cast(lua_State *, cast(unsigned long, luaL_checknumber(L, 1)));
lua_register(L1, "mathlibopen", lua_mathlibopen);
lua_register(L1, "strlibopen", lua_strlibopen);
lua_register(L1, "iolibopen", lua_iolibopen);
lua_register(L1, "dblibopen", lua_dblibopen);
lua_register(L1, "baselibopen", lua_baselibopen);
static const luaL_reg libs[] = {
{"mathlibopen", luaopen_math},
{"strlibopen", luaopen_string},
{"iolibopen", luaopen_io},
{"tablibopen", luaopen_table},
{"dblibopen", luaopen_debug},
{"baselibopen", luaopen_base},
{NULL, NULL}
};
lua_State *L1 = cast(lua_State *,
cast(unsigned long, luaL_checknumber(L, 1)));
lua_pushvalue(L1, LUA_GLOBALSINDEX);
luaL_openlib(L1, NULL, libs, 0);
return 0;
}
@@ -467,8 +496,9 @@ static int doremote (lua_State *L) {
status = lua_pcall(L1, 0, LUA_MULTRET, 0);
if (status != 0) {
lua_pushnil(L);
lua_pushnumber(L, status);
return 2;
lua_pushintegral(L, status);
lua_pushstring(L, lua_tostring(L1, -1));
return 3;
}
else {
int i = 0;
@@ -481,10 +511,17 @@ static int doremote (lua_State *L) {
static int log2_aux (lua_State *L) {
lua_pushnumber(L, luaO_log2(luaL_checkint(L, 1)));
lua_pushintegral(L, luaO_log2(luaL_checkint(L, 1)));
return 1;
}
static int int2fb_aux (lua_State *L) {
int b = luaO_int2fb(luaL_checkint(L, 1));
lua_pushintegral(L, b);
lua_pushintegral(L, fb2int(b));
return 2;
}
static int test_do (lua_State *L) {
const char *p = luaL_checkstring(L, 1);
@@ -551,31 +588,31 @@ static int testC (lua_State *L) {
const char *inst = getname;
if EQ("") return 0;
else if EQ("isnumber") {
lua_pushnumber(L, lua_isnumber(L, getnum));
lua_pushintegral(L, lua_isnumber(L, getnum));
}
else if EQ("isstring") {
lua_pushnumber(L, lua_isstring(L, getnum));
lua_pushintegral(L, lua_isstring(L, getnum));
}
else if EQ("istable") {
lua_pushnumber(L, lua_istable(L, getnum));
lua_pushintegral(L, lua_istable(L, getnum));
}
else if EQ("iscfunction") {
lua_pushnumber(L, lua_iscfunction(L, getnum));
lua_pushintegral(L, lua_iscfunction(L, getnum));
}
else if EQ("isfunction") {
lua_pushnumber(L, lua_isfunction(L, getnum));
lua_pushintegral(L, lua_isfunction(L, getnum));
}
else if EQ("isuserdata") {
lua_pushnumber(L, lua_isuserdata(L, getnum));
lua_pushintegral(L, lua_isuserdata(L, getnum));
}
else if EQ("isudataval") {
lua_pushnumber(L, lua_islightuserdata(L, getnum));
lua_pushintegral(L, lua_islightuserdata(L, getnum));
}
else if EQ("isnil") {
lua_pushnumber(L, lua_isnil(L, getnum));
lua_pushintegral(L, lua_isnil(L, getnum));
}
else if EQ("isnull") {
lua_pushnumber(L, lua_isnone(L, getnum));
lua_pushintegral(L, lua_isnone(L, getnum));
}
else if EQ("tonumber") {
lua_pushnumber(L, lua_tonumber(L, getnum));
@@ -584,11 +621,8 @@ static int testC (lua_State *L) {
const char *s = lua_tostring(L, getnum);
lua_pushstring(L, s);
}
else if EQ("tonumber") {
lua_pushnumber(L, lua_tonumber(L, getnum));
}
else if EQ("strlen") {
lua_pushnumber(L, lua_strlen(L, getnum));
lua_pushintegral(L, lua_strlen(L, getnum));
}
else if EQ("tocfunction") {
lua_pushcfunction(L, lua_tocfunction(L, getnum));
@@ -597,7 +631,7 @@ static int testC (lua_State *L) {
return getnum;
}
else if EQ("gettop") {
lua_pushnumber(L, lua_gettop(L));
lua_pushintegral(L, lua_gettop(L));
}
else if EQ("settop") {
lua_settop(L, getnum);
@@ -606,7 +640,7 @@ static int testC (lua_State *L) {
lua_pop(L, getnum);
}
else if EQ("pushnum") {
lua_pushnumber(L, getnum);
lua_pushintegral(L, getnum);
}
else if EQ("pushnil") {
lua_pushnil(L);
@@ -615,7 +649,7 @@ static int testC (lua_State *L) {
lua_pushboolean(L, getnum);
}
else if EQ("tobool") {
lua_pushnumber(L, lua_toboolean(L, getnum));
lua_pushintegral(L, lua_toboolean(L, getnum));
}
else if EQ("pushvalue") {
lua_pushvalue(L, getnum);
@@ -683,6 +717,16 @@ static int testC (lua_State *L) {
else if EQ("type") {
lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
}
else if EQ("getn") {
int i = getnum;
lua_pushintegral(L, luaL_getn(L, i));
}
else if EQ("setn") {
int i = getnum;
int n = cast(int, lua_tonumber(L, -1));
luaL_setn(L, i, n);
lua_pop(L, 1);
}
else luaL_error(L, "unknown instruction %s", buff);
}
return 0;
@@ -754,6 +798,7 @@ static const struct luaL_reg tests_funcs[] = {
{"d2s", d2s},
{"s2d", s2d},
{"metatable", metatable},
{"upvalue", upvalue},
{"newuserdata", newuserdata},
{"pushuserdata", pushuserdata},
{"udataval", udataval},
@@ -762,6 +807,7 @@ static const struct luaL_reg tests_funcs[] = {
{"closestate", closestate},
{"doremote", doremote},
{"log2", log2_aux},
{"int2fb", int2fb_aux},
{"totalmem", mem_query},
{"resume", coresume},
{"setyhook", setyhook},
@@ -777,7 +823,15 @@ static void fim (void) {
}
static int l_panic (lua_State *L) {
UNUSED(L);
fprintf(stderr, "unable to recover; exiting\n");
return 0;
}
int luaB_opentests (lua_State *L) {
lua_atpanic(L, l_panic);
lua_userstateopen(L); /* init lock */
lua_state = L; /* keep first state to be opened */
luaL_openlib(L, "T", tests_funcs, 0);
@@ -792,6 +846,7 @@ int main (int argc, char *argv[]) {
if (limit)
memdebug_memlimit = strtoul(limit, NULL, 10);
l_main(argc, argv);
return 0;
}
#endif

4
ltm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 1.104 2002/11/14 11:51:50 roberto Exp roberto $
** $Id: ltm.c,v 1.105 2002/12/04 17:38:31 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -49,7 +49,7 @@ const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
const TObject *tm = luaH_getstr(events, ename);
lua_assert(event <= TM_EQ);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= (1u<<event); /* cache this fact */
events->flags |= cast(lu_byte, 1u<<event); /* cache this fact */
return NULL;
}
else return tm;

59
lua.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.112 2002/12/04 17:28:27 roberto Exp roberto $
** $Id: lua.c,v 1.121 2003/03/24 12:40:01 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@@ -26,10 +26,14 @@
#endif
#ifdef _POSIX_SOURCE
/*
** definition of `isatty'
*/
#ifdef _POSIX_C_SOURCE
#include <unistd.h>
#define stdin_is_tty() isatty(0)
#else
static int isatty (int x) { return x==0; } /* assume stdin is a tty */
#define stdin_is_tty() 1 /* assume stdin is a tty */
#endif
@@ -43,6 +47,9 @@ static int isatty (int x) { return x==0; } /* assume stdin is a tty */
#define PROMPT2 ">> "
#endif
#ifndef PROGNAME
#define PROGNAME "lua"
#endif
#ifndef lua_userinit
#define lua_userinit(L) openstdlibs(L)
@@ -56,17 +63,18 @@ static int isatty (int x) { return x==0; } /* assume stdin is a tty */
static lua_State *L = NULL;
static const char *progname;
static const char *progname = PROGNAME;
static const luaL_reg lualibs[] = {
{"baselib", lua_baselibopen},
{"tablib", lua_tablibopen},
{"iolib", lua_iolibopen},
{"strlib", lua_strlibopen},
{"mathlib", lua_mathlibopen},
{"dblib", lua_dblibopen},
{"base", luaopen_base},
{"table", luaopen_table},
{"io", luaopen_io},
{"string", luaopen_string},
{"math", luaopen_math},
{"debug", luaopen_debug},
{"loadlib", luaopen_loadlib},
/* add your libraries here */
LUA_EXTRALIBS
{NULL, NULL}
@@ -134,13 +142,6 @@ static int lcall (int narg, int clear) {
}
static int l_panic (lua_State *l) {
(void)l;
l_message(progname, "unable to recover; exiting");
return 0;
}
static void print_version (void) {
l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT);
}
@@ -285,7 +286,8 @@ static void manual_input (void) {
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
l_message(progname, "error calling `print'");
l_message(progname, lua_pushfstring(L, "error calling `print' (%s)",
lua_tostring(L, -1)));
}
}
lua_settop(L, 0); /* clear stack */
@@ -296,7 +298,7 @@ static void manual_input (void) {
static int handle_argv (char *argv[], int *interactive) {
if (argv[1] == NULL) { /* no more arguments? */
if (isatty(0)) {
if (stdin_is_tty()) {
print_version();
manual_input();
}
@@ -309,6 +311,10 @@ static int handle_argv (char *argv[], int *interactive) {
if (argv[i][0] != '-') break; /* not an option? */
switch (argv[i][1]) { /* option */
case '-': { /* `--' */
if (argv[i][2] != '\0') {
print_usage();
return 1;
}
i++; /* skip this argument */
goto endloop; /* stop handling arguments */
}
@@ -329,10 +335,10 @@ static int handle_argv (char *argv[], int *interactive) {
if (*chunk == '\0') chunk = argv[++i];
if (chunk == NULL) {
print_usage();
return EXIT_FAILURE;
return 1;
}
if (dostring(chunk, "=<command line>") != 0)
return EXIT_FAILURE;
return 1;
break;
}
case 'l': {
@@ -340,10 +346,10 @@ static int handle_argv (char *argv[], int *interactive) {
if (*filename == '\0') filename = argv[++i];
if (filename == NULL) {
print_usage();
return EXIT_FAILURE;
return 1;
}
if (load_file(filename))
return EXIT_FAILURE; /* stop if file fails */
return 1; /* stop if file fails */
break;
}
case 'c': {
@@ -356,7 +362,7 @@ static int handle_argv (char *argv[], int *interactive) {
}
default: {
print_usage();
return EXIT_FAILURE;
return 1;
}
}
} endloop:
@@ -373,7 +379,7 @@ static int handle_argv (char *argv[], int *interactive) {
static void openstdlibs (lua_State *l) {
const luaL_reg *lib = lualibs;
for (; lib->name; lib++) {
for (; lib->func; lib++) {
lib->func(l); /* open library */
lua_settop(l, 0); /* discard any results */
}
@@ -401,7 +407,7 @@ static int pmain (lua_State *l) {
struct Smain *s = (struct Smain *)lua_touserdata(l, 1);
int status;
int interactive = 0;
progname = s->argv[0];
if (s->argv[0] && s->argv[0][0]) progname = s->argv[0];
L = l;
lua_userinit(l); /* open libraries */
status = handle_luainit();
@@ -424,7 +430,6 @@ int main (int argc, char *argv[]) {
}
s.argc = argc;
s.argv = argv;
lua_atpanic(l, l_panic);
status = lua_cpcall(l, &pmain, &s);
report(status);
lua_close(l);

20
lua.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.168 2002/11/26 12:53:29 roberto Exp roberto $
** $Id: lua.h,v 1.174 2003/02/27 11:52:30 roberto Exp roberto $
** Lua - An Extensible Extension Language
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
** http://www.lua.org mailto:info@lua.org
@@ -14,8 +14,8 @@
#include <stddef.h>
#define LUA_VERSION "Lua 5.0 (beta)"
#define LUA_COPYRIGHT "Copyright (C) 1994-2002 Tecgraf, PUC-Rio"
#define LUA_VERSION "Lua 5.0"
#define LUA_COPYRIGHT "Copyright (C) 1994-2003 Tecgraf, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
@@ -167,8 +167,9 @@ LUA_API void lua_gettable (lua_State *L, int idx);
LUA_API void lua_rawget (lua_State *L, int idx);
LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
LUA_API void lua_newtable (lua_State *L);
LUA_API void *lua_newuserdata (lua_State *L, size_t sz);
LUA_API int lua_getmetatable (lua_State *L, int objindex);
LUA_API void lua_getglobals (lua_State *L, int idx);
LUA_API void lua_getfenv (lua_State *L, int idx);
/*
@@ -178,7 +179,7 @@ LUA_API void lua_settable (lua_State *L, int idx);
LUA_API void lua_rawset (lua_State *L, int idx);
LUA_API void lua_rawseti (lua_State *L, int idx, int n);
LUA_API int lua_setmetatable (lua_State *L, int objindex);
LUA_API int lua_setglobals (lua_State *L, int idx);
LUA_API int lua_setfenv (lua_State *L, int idx);
/*
@@ -218,8 +219,6 @@ LUA_API int lua_next (lua_State *L, int idx);
LUA_API void lua_concat (lua_State *L, int n);
LUA_API void *lua_newuserdata (lua_State *L, size_t sz);
/*
@@ -317,6 +316,7 @@ LUA_API int lua_pushupvalues (lua_State *L);
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
#define LUA_HOOKCOUNT 3
#define LUA_HOOKTAILRET 4
/*
@@ -336,6 +336,8 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
LUA_API lua_Hook lua_gethook (lua_State *L);
@@ -349,7 +351,7 @@ struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) `global', `local', `field', `method' */
const char *what; /* (S) `Lua' function, `C' function, Lua `main' */
const char *what; /* (S) `Lua', `C', `main', `tail' */
const char *source; /* (S) */
int currentline; /* (l) */
int nups; /* (u) number of upvalues */
@@ -363,7 +365,7 @@ struct lua_Debug {
/******************************************************************************
* Copyright (C) 2002 Tecgraf, PUC-Rio. All rights reserved.
* Copyright (C) 1994-2003 Tecgraf, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the

View File

@@ -1,5 +1,5 @@
/*
** $Id: lualib.h,v 1.24 2002/06/18 17:42:52 roberto Exp roberto $
** $Id: lualib.h,v 1.27 2003/03/17 13:04:58 roberto Exp roberto $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -12,28 +12,31 @@
#ifndef LUALIB_API
#define LUALIB_API extern
#define LUALIB_API LUA_API
#endif
#define LUA_COLIBNAME "coroutine"
LUALIB_API int lua_baselibopen (lua_State *L);
LUALIB_API int luaopen_base (lua_State *L);
#define LUA_TABLIBNAME "table"
LUALIB_API int lua_tablibopen (lua_State *L);
LUALIB_API int luaopen_table (lua_State *L);
#define LUA_IOLIBNAME "io"
#define LUA_OSLIBNAME "os"
LUALIB_API int lua_iolibopen (lua_State *L);
LUALIB_API int luaopen_io (lua_State *L);
#define LUA_STRLIBNAME "string"
LUALIB_API int lua_strlibopen (lua_State *L);
LUALIB_API int luaopen_string (lua_State *L);
#define LUA_MATHLIBNAME "math"
LUALIB_API int lua_mathlibopen (lua_State *L);
LUALIB_API int luaopen_math (lua_State *L);
#define LUA_DBLIBNAME "debug"
LUALIB_API int lua_dblibopen (lua_State *L);
LUALIB_API int luaopen_debug (lua_State *L);
LUALIB_API int luaopen_loadlib (lua_State *L);
/* to help testing the libraries */
@@ -41,4 +44,13 @@ LUALIB_API int lua_dblibopen (lua_State *L);
#define lua_assert(c) /* empty */
#endif
/* compatibility code */
#define lua_baselibopen luaopen_base
#define lua_tablibopen luaopen_table
#define lua_iolibopen luaopen_io
#define lua_strlibopen luaopen_string
#define lua_mathlibopen luaopen_math
#define lua_dblibopen luaopen_debug
#endif

View File

@@ -1,5 +1,5 @@
/*
** $Id: lundump.c,v 1.57 2002/11/14 16:15:53 roberto Exp roberto $
** $Id: lundump.c,v 1.49 2003/04/07 20:34:20 lhf Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -104,7 +104,7 @@ static TString* LoadString (LoadState* S)
{
char* s=luaZ_openspace(S->L,S->b,size);
ezread(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
}
}
@@ -138,6 +138,18 @@ static void LoadLines (LoadState* S, Proto* f)
LoadVector(S,f->lineinfo,size,sizeof(*f->lineinfo));
}
static void LoadUpvalues (LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
if (n!=0 && n!=f->nups)
luaG_runerror(S->L,"bad nupvalues in %s: read %d; expected %d",
S->name,n,f->nups);
f->upvalues=luaM_newvector(S->L,n,TString*);
f->sizeupvalues=n;
for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
}
static Proto* LoadFunction (LoadState* S, TString* p);
static void LoadConstants (LoadState* S, Proto* f)
@@ -177,12 +189,13 @@ static Proto* LoadFunction (LoadState* S, TString* p)
Proto* f=luaF_newproto(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->lineDefined=LoadInt(S);
f->nupvalues=LoadByte(S);
f->nups=LoadByte(S);
f->numparams=LoadByte(S);
f->is_vararg=LoadByte(S);
f->maxstacksize=LoadByte(S);
LoadLocals(S,f);
LoadLines(S,f);
LoadLocals(S,f);
LoadUpvalues(S,f);
LoadConstants(S,f);
LoadCode(S,f);
#ifndef TRUST_BINARIES
@@ -213,14 +226,14 @@ static void TestSize (LoadState* S, int s, const char* what)
static void LoadHeader (LoadState* S)
{
int version;
lua_Number x=0,tx=TEST_NUMBER;
lua_Number x,tx=TEST_NUMBER;
LoadSignature(S);
version=LoadByte(S);
if (version>VERSION)
luaG_runerror(S->L,"%s too new: "
"read version %d.%d; expected at most %d.%d",
S->name,V(version),V(VERSION));
if (version<VERSION0) /* check last major change */
if (version<VERSION0) /* check last major change */
luaG_runerror(S->L,"%s too old: "
"read version %d.%d; expected at least %d.%d",
S->name,V(version),V(VERSION0));

View File

@@ -1,5 +1,5 @@
/*
** $Id: lundump.h,v 1.28 2002/10/09 13:42:01 roberto Exp roberto $
** $Id: lundump.h,v 1.30 2003/04/07 20:34:20 lhf Exp $
** load pre-compiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -11,24 +11,24 @@
#include "lzio.h"
/* load one chunk; from lundump.c */
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer *buff);
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff);
/* find byte order; from lundump.c */
int luaU_endianness (void);
/* dump one chunk; from dump.c */
void luaU_dump (lua_State *L, const Proto* Main, lua_Chunkwriter w, void* data);
/* dump one chunk; from ldump.c */
void luaU_dump (lua_State* L, const Proto* Main, lua_Chunkwriter w, void* data);
/* print one chunk; from print.c */
void luaU_print (const Proto* Main);
/* definitions for headers of binary files */
#define LUA_SIGNATURE "\033Lua" /* binary files start with <esc>Lua */
#define LUA_SIGNATURE "\033Lua" /* binary files start with "<esc>Lua" */
#define VERSION 0x50 /* last format change was in 5.0 */
#define VERSION0 0x50 /* last major change was in 5.0 */
/* a multiple of PI for testing native format */
/* multiplying by 1E8 gives non-trivial integer values */
#define TEST_NUMBER 3.14159265358979323846E8
/* multiplying by 1E7 gives non-trivial integer values */
#define TEST_NUMBER ((lua_Number)3.14159265358979323846E7)
#endif

94
lvm.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lvm.c,v 1.272 2002/12/06 17:09:00 roberto Exp roberto $
** $Id: lvm.c,v 1.283 2003/03/31 13:00:25 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -9,6 +9,9 @@
#include <stdlib.h>
#include <string.h>
/* needed only when `lua_number2str' uses `sprintf' */
#include <stdio.h>
#define lvm_c
#include "lua.h"
@@ -29,7 +32,6 @@
/* function to convert a lua_Number to a string */
#ifndef lua_number2str
#include <stdio.h>
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#endif
@@ -204,6 +206,33 @@ static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
}
static const TObject *get_compTM (lua_State *L, Table *mt1, Table *mt2,
TMS event) {
const TObject *tm1 = fasttm(L, mt1, event);
const TObject *tm2;
if (tm1 == NULL) return NULL; /* no metamethod */
if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
tm2 = fasttm(L, mt2, event);
if (tm2 == NULL) return NULL; /* no metamethod */
if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
return tm1;
return NULL;
}
static int call_orderTM (lua_State *L, const TObject *p1, const TObject *p2,
TMS event) {
const TObject *tm1 = luaT_gettmbyobj(L, p1, event);
const TObject *tm2;
if (ttisnil(tm1)) return -1; /* no metamethod? */
tm2 = luaT_gettmbyobj(L, p2, event);
if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
return -1;
callTMres(L, tm1, p1, p2);
return !l_isfalse(L->top);
}
static int luaV_strcmp (const TString *ls, const TString *rs) {
const char *l = getstr(ls);
size_t ll = ls->tsv.len;
@@ -227,35 +256,37 @@ static int luaV_strcmp (const TString *ls, const TString *rs) {
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return nvalue(l) < nvalue(r);
else if (ttisstring(l))
return luaV_strcmp(tsvalue(l), tsvalue(r)) < 0;
else if (call_binTM(L, l, r, L->top, TM_LT))
return !l_isfalse(L->top);
else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
return res;
return luaG_ordererror(L, l, r);
}
static int luaV_lessequal (lua_State *L, const TObject *l, const TObject *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return nvalue(l) <= nvalue(r);
else if (ttisstring(l))
return luaV_strcmp(tsvalue(l), tsvalue(r)) <= 0;
else if (call_binTM(L, l, r, L->top, TM_LE)) /* first try `le' */
return !l_isfalse(L->top);
else if (call_binTM(L, r, l, L->top, TM_LT)) /* else try `lt' */
return l_isfalse(L->top);
else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
return res;
else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
return !res;
return luaG_ordererror(L, l, r);
}
int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
const TObject *tm = NULL;
const TObject *tm;
lua_assert(ttype(t1) == ttype(t2));
switch (ttype(t1)) {
case LUA_TNIL: return 1;
@@ -264,20 +295,18 @@ int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2) {
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
case LUA_TUSERDATA: {
if (uvalue(t1) == uvalue(t2)) return 1;
else if ((tm = fasttm(L, uvalue(t1)->uv.metatable, TM_EQ)) == NULL &&
(tm = fasttm(L, uvalue(t2)->uv.metatable, TM_EQ)) == NULL)
return 0; /* no TM */
else break; /* will try TM */
tm = get_compTM(L, uvalue(t1)->uv.metatable, uvalue(t2)->uv.metatable,
TM_EQ);
break; /* will try TM */
}
case LUA_TTABLE: {
if (hvalue(t1) == hvalue(t2)) return 1;
else if ((tm = fasttm(L, hvalue(t1)->metatable, TM_EQ)) == NULL &&
(tm = fasttm(L, hvalue(t2)->metatable, TM_EQ)) == NULL)
return 0; /* no TM */
else break; /* will try TM */
tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
break; /* will try TM */
}
default: return gcvalue(t1) == gcvalue(t2);
}
if (tm == NULL) return 0; /* no TM? */
callTMres(L, tm, t1, t2); /* call TM */
return !l_isfalse(L->top);
}
@@ -328,11 +357,10 @@ static void Arith (lua_State *L, StkId ra,
case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
case TM_POW: {
const TObject *f = luaH_getstr(hvalue(registry(L)),
G(L)->tmname[TM_POW]);
const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
ptrdiff_t res = savestack(L, ra);
if (!ttisfunction(f))
luaG_runerror(L, "`pow' (for `^' operator) is not a function");
luaG_runerror(L, "`__pow' (`^' operator) is not a function");
callTMres(L, f, b, c);
ra = restorestack(L, res); /* previous call may change stack */
setobjs2s(ra, L->top);
@@ -468,7 +496,7 @@ StkId luaV_execute (lua_State *L) {
}
case OP_NEWTABLE: {
int b = GETARG_B(i);
if (b > 0) b = twoto(b-1);
b = fb2int(b);
sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
luaC_checkGC(L);
break;
@@ -621,6 +649,7 @@ StkId luaV_execute (lua_State *L) {
(L->ci - 1)->top = L->top = base+aux; /* correct top */
lua_assert(L->ci->state & CI_SAVEDPC);
(L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
(L->ci - 1)->u.l.tailcalls++; /* one more call lost */
(L->ci - 1)->state = CI_SAVEDPC;
L->ci--; /* remove new frame */
L->base = L->ci->base;
@@ -630,7 +659,7 @@ StkId luaV_execute (lua_State *L) {
break;
}
case OP_RETURN: {
CallInfo *ci = L->ci - 1;
CallInfo *ci = L->ci - 1; /* previous function frame */
int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1;
lua_assert(L->ci->state & CI_HASFRAME);
@@ -638,12 +667,15 @@ StkId luaV_execute (lua_State *L) {
L->ci->state = CI_SAVEDPC; /* deactivate current function */
L->ci->u.l.savedpc = pc;
/* previous function was running `here'? */
if (!(ci->state & CI_CALLING))
if (!(ci->state & CI_CALLING)) {
lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
return ra; /* no: return */
else { /* yes: continue its execution (go through) */
}
else { /* yes: continue its execution */
int nresults;
lua_assert(ttisfunction(ci->base - 1));
lua_assert(ci->state & CI_SAVEDPC);
lua_assert(ci->u.l.pc == &pc &&
ttisfunction(ci->base - 1) &&
(ci->state & CI_SAVEDPC));
lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
luaD_poscall(L, nresults, ra);
@@ -652,7 +684,7 @@ StkId luaV_execute (lua_State *L) {
}
}
case OP_FORLOOP: {
lua_Number step, index, limit;
lua_Number step, idx, limit;
const TObject *plimit = ra+1;
const TObject *pstep = ra+2;
if (!ttisnumber(ra))
@@ -662,11 +694,11 @@ StkId luaV_execute (lua_State *L) {
if (!tonumber(pstep, ra+2))
luaG_runerror(L, "`for' step must be a number");
step = nvalue(pstep);
index = nvalue(ra) + step; /* increment index */
idx = nvalue(ra) + step; /* increment index */
limit = nvalue(plimit);
if (step > 0 ? index <= limit : index >= limit) {
if (step > 0 ? idx <= limit : idx >= limit) {
dojump(pc, GETARG_sBx(i)); /* jump back */
chgnvalue(ra, index); /* update index */
chgnvalue(ra, idx); /* update index */
}
break;
}
@@ -727,7 +759,7 @@ StkId luaV_execute (lua_State *L) {
Closure *ncl;
int nup, j;
p = cl->p->p[GETARG_Bx(i)];
nup = p->nupvalues;
nup = p->nups;
ncl = luaF_newLclosure(L, nup, &cl->g);
ncl->l.p = p;
for (j=0; j<nup; j++, pc++) {

6
lzio.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lzio.c,v 1.22 2002/10/08 18:46:08 roberto Exp roberto $
** $Id: lzio.c,v 1.23 2002/12/04 17:38:31 roberto Exp roberto $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
@@ -22,7 +22,7 @@ int luaZ_fill (ZIO *z) {
if (buff == NULL || size == 0) return EOZ;
z->n = size - 1;
z->p = buff;
return *(z->p++);
return char2int(*(z->p++));
}
@@ -33,7 +33,7 @@ int luaZ_lookahead (ZIO *z) {
z->n++;
z->p--;
}
return *z->p;
return char2int(*z->p);
}

9
lzio.h
View File

@@ -1,5 +1,5 @@
/*
** $Id: lzio.h,v 1.13 2002/08/05 18:45:02 roberto Exp roberto $
** $Id: lzio.h,v 1.14 2002/10/08 18:46:08 roberto Exp roberto $
** Buffered streams
** See Copyright Notice in lua.h
*/
@@ -15,9 +15,10 @@
typedef struct Zio ZIO;
#define zgetc(z) (((z)->n--)>0 ? \
cast(int, cast(unsigned char, *(z)->p++)) : \
luaZ_fill(z))
#define char2int(c) cast(int, cast(unsigned char, (c)))
#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
#define zname(z) ((z)->name)

View File

@@ -1,5 +1,5 @@
#
## $Id: makefile,v 1.38 2002/10/25 21:38:17 roberto Exp $
## $Id: makefile,v 1.40 2003/03/19 21:27:30 roberto Exp roberto $
## Makefile
## See Copyright Notice in lua.h
#
@@ -7,22 +7,14 @@
#CONFIGURATION
# define (undefine) USE_POPEN if your system (does not) support piped I/O
#
# define (undefine) _POSIX_SOURCE if your system is (not) POSIX compliant
#
# define LUA_NUM_TYPE if you need numbers to be different from double
# (for instance, -DLUA_NUM_TYPE=float)
# you may need to adapat the code, too.
# DEBUG = -g -DLUA_USER_H='"ltests.h"' # -DHARDSTACKTESTS -DEXTERNMEMCHECK
# -DEXTERNMEMCHECK -DHARDSTACKTESTS
# DEBUG = -g -DLUA_USER_H='"ltests.h"'
OPTIMIZE = -O2 \
# -D'lua_number2int(i,d)=__asm__("fldl %1\nfistpl %0":"=m"(i):"m"(d))' \
# -fomit-frame-pointer
-D'lua_number2int(i,d)=__asm__("fldl %1\nfistpl %0":"=m"(i):"m"(d))' \
# -fomit-frame-pointer
CONFIG = -D_POSIX_SOURCE $(DEBUG) $(OPTIMIZE) # -DUSE_POPEN
CONFIG = $(DEBUG) $(OPTIMIZE) -DLUA_COMPATUPSYNTAX -DUSE_TMPNAME -DUSE_DLOPEN
# Compilation parameters
@@ -39,7 +31,7 @@ CWARNS = -Wall -pedantic \
# -Wtraditional \
# -Wcast-qual
CFLAGS = $(CONFIG) $(CWARNS) -ansi
CFLAGS = $(CONFIG) $(CWARNS) # -ansi
# To make early versions
@@ -80,11 +72,12 @@ LIBOBJS = \
lmathlib.o \
liolib.o \
lstrlib.o \
ldblib.o
ldblib.o \
loadlib.o
lua : lua.o liblua.a liblualib.a
$(CC) $(CFLAGS) -o $@ lua.o -L. -llua -llualib -lm
$(CC) $(CFLAGS) -o $@ lua.o -Wl,-E -L. -llua -llualib -lm -ldl
liblua.a : $(LUAOBJS)
$(AR) $(ARFLAGS) $@ $?
@@ -137,6 +130,7 @@ lmem.o: lmem.c lua.h ldebug.h lstate.h lobject.h llimits.h ltm.h lzio.h \
ldo.h lmem.h
lobject.o: lobject.c lua.h ldo.h lobject.h llimits.h lstate.h ltm.h \
lzio.h lmem.h lstring.h lvm.h
loadlib.o: loadlib.c lua.h lauxlib.h lualib.h
lopcodes.o: lopcodes.c lua.h lobject.h llimits.h lopcodes.h
lparser.o: lparser.c lua.h lcode.h llex.h lobject.h llimits.h lzio.h \
lopcodes.h lparser.h ltable.h ldebug.h lstate.h ltm.h lfunc.h lmem.h \

4487
manual.tex

File diff suppressed because it is too large Load Diff