summaryrefslogtreecommitdiff
path: root/src/lapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lapi.c')
-rw-r--r--src/lapi.c430
1 files changed, 235 insertions, 195 deletions
diff --git a/src/lapi.c b/src/lapi.c
index d5dd9ca4..1b086a0b 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,11 +1,12 @@
/*
-** $Id: lapi.c,v 1.235 2003/04/07 14:36:08 roberto Exp $
+** $Id: lapi.c,v 2.5 2004/03/23 17:07:34 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
#include <assert.h>
+#include <stdarg.h>
#include <string.h>
#define lapi_c
@@ -27,6 +28,12 @@
#include "lvm.h"
+/* function to convert a lua_Number to lua_Integer (with any rounding method) */
+#ifndef lua_number2integer
+#define lua_number2integer(i,n) ((i)=(lua_Integer)(n))
+#endif
+
+
const char lua_ident[] =
"$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
"$Authors: " LUA_AUTHORS " $\n"
@@ -35,63 +42,44 @@ const char lua_ident[] =
#ifndef api_check
-#define api_check(L, o) /*{ assert(o); }*/
+#define api_check(L, o) lua_assert(o)
#endif
#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base))
-#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
+#define api_checkvalidindex(L, i) api_check(L, (i) != &luaO_nilobject)
+#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
-static TObject *negindex (lua_State *L, int idx) {
- if (idx > LUA_REGISTRYINDEX) {
+static TValue *luaA_index (lua_State *L, int idx) {
+ if (idx > 0) {
+ TValue *o = L->base + (idx - 1);
+ api_check(L, idx <= L->stack_last - L->base);
+ if (o >= L->top) return cast(TValue *, &luaO_nilobject);
+ else return o;
+ }
+ else if (idx > LUA_REGISTRYINDEX) {
api_check(L, idx != 0 && -idx <= L->top - L->base);
- return L->top+idx;
+ return L->top + idx;
}
else switch (idx) { /* pseudo-indices */
case LUA_REGISTRYINDEX: return registry(L);
case LUA_GLOBALSINDEX: return gt(L);
default: {
- TObject *func = (L->base - 1);
+ Closure *func = curr_func(L);
idx = LUA_GLOBALSINDEX - idx;
- lua_assert(iscfunction(func));
- return (idx <= clvalue(func)->c.nupvalues)
- ? &clvalue(func)->c.upvalue[idx-1]
- : NULL;
+ return (idx <= func->c.nupvalues)
+ ? &func->c.upvalue[idx-1]
+ : cast(TValue *, &luaO_nilobject);
}
}
}
-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;
- }
-}
-
-
-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, idx);
-}
-
-
-void luaA_pushobject (lua_State *L, const TObject *o) {
- setobj2s(L->top, o);
+void luaA_pushobject (lua_State *L, const TValue *o) {
+ setobj2s(L, L->top, o);
incr_top(L);
}
@@ -114,11 +102,12 @@ LUA_API int lua_checkstack (lua_State *L, int size) {
LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
int i;
+ if (from == to) return;
lua_lock(to);
api_checknelems(from, n);
from->top -= n;
for (i = 0; i < n; i++) {
- setobj2s(to->top, from->top + i);
+ setobj2s(to, to->top, from->top + i);
api_incr_top(to);
}
lua_unlock(to);
@@ -140,7 +129,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
lua_lock(L);
luaC_checkGC(L);
L1 = luaE_newthread(L);
- setthvalue(L->top, L1);
+ setthvalue(L, L->top, L1);
api_incr_top(L);
lua_unlock(L);
lua_userstateopen(L1);
@@ -179,7 +168,8 @@ LUA_API void lua_remove (lua_State *L, int idx) {
StkId p;
lua_lock(L);
p = luaA_index(L, idx);
- while (++p < L->top) setobjs2s(p-1, p);
+ api_checkvalidindex(L, p);
+ while (++p < L->top) setobjs2s(L, p-1, p);
L->top--;
lua_unlock(L);
}
@@ -190,16 +180,22 @@ LUA_API void lua_insert (lua_State *L, int idx) {
StkId q;
lua_lock(L);
p = luaA_index(L, idx);
- for (q = L->top; q>p; q--) setobjs2s(q, q-1);
- setobjs2s(p, L->top);
+ api_checkvalidindex(L, p);
+ for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
+ setobjs2s(L, p, L->top);
lua_unlock(L);
}
LUA_API void lua_replace (lua_State *L, int idx) {
+ StkId o;
lua_lock(L);
api_checknelems(L, 1);
- setobj(luaA_index(L, idx), L->top - 1); /* write barrier */
+ o = luaA_index(L, idx);
+ api_checkvalidindex(L, o);
+ setobj(L, o, L->top - 1);
+ if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
+ luaC_barrier(L, curr_func(L), L->top - 1);
L->top--;
lua_unlock(L);
}
@@ -207,7 +203,7 @@ LUA_API void lua_replace (lua_State *L, int idx) {
LUA_API void lua_pushvalue (lua_State *L, int idx) {
lua_lock(L);
- setobj2s(L->top, luaA_index(L, idx));
+ setobj2s(L, L->top, luaA_index(L, idx));
api_incr_top(L);
lua_unlock(L);
}
@@ -220,8 +216,8 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
LUA_API int lua_type (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- return (o == NULL) ? LUA_TNONE : ttype(o);
+ StkId o = luaA_index(L, idx);
+ return (o == &luaO_nilobject) ? LUA_TNONE : ttype(o);
}
@@ -232,15 +228,15 @@ LUA_API const char *lua_typename (lua_State *L, int t) {
LUA_API int lua_iscfunction (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- return (o == NULL) ? 0 : iscfunction(o);
+ StkId o = luaA_index(L, idx);
+ return iscfunction(o);
}
LUA_API int lua_isnumber (lua_State *L, int idx) {
- TObject n;
- const TObject *o = luaA_indexAcceptable(L, idx);
- return (o != NULL && tonumber(o, &n));
+ TValue n;
+ const TValue *o = luaA_index(L, idx);
+ return tonumber(o, &n);
}
@@ -251,16 +247,16 @@ LUA_API int lua_isstring (lua_State *L, int idx) {
LUA_API int lua_isuserdata (lua_State *L, int idx) {
- const TObject *o = luaA_indexAcceptable(L, idx);
- return (o != NULL && (ttisuserdata(o) || ttislightuserdata(o)));
+ const TValue *o = luaA_index(L, idx);
+ return (ttisuserdata(o) || ttislightuserdata(o));
}
LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
- StkId o1 = luaA_indexAcceptable(L, index1);
- StkId o2 = luaA_indexAcceptable(L, index2);
- return (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
- : luaO_rawequalObj(o1, o2);
+ StkId o1 = luaA_index(L, index1);
+ StkId o2 = luaA_index(L, index2);
+ return (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0
+ : luaO_rawequalObj(o1, o2);
}
@@ -268,10 +264,10 @@ LUA_API int lua_equal (lua_State *L, int index1, int index2) {
StkId o1, o2;
int i;
lua_lock(L); /* may call tag method */
- o1 = luaA_indexAcceptable(L, index1);
- o2 = luaA_indexAcceptable(L, index2);
- i = (o1 == NULL || o2 == NULL) ? 0 /* index out of range */
- : equalobj(L, o1, o2);
+ o1 = luaA_index(L, index1);
+ o2 = luaA_index(L, index2);
+ i = (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0
+ : equalobj(L, o1, o2);
lua_unlock(L);
return i;
}
@@ -281,10 +277,10 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
StkId o1, o2;
int i;
lua_lock(L); /* may call tag method */
- o1 = luaA_indexAcceptable(L, index1);
- o2 = luaA_indexAcceptable(L, index2);
- i = (o1 == NULL || o2 == NULL) ? 0 /* index out-of-range */
- : luaV_lessthan(L, o1, o2);
+ o1 = luaA_index(L, index1);
+ o2 = luaA_index(L, index2);
+ i = (o1 == &luaO_nilobject || o2 == &luaO_nilobject) ? 0
+ : luaV_lessthan(L, o1, o2);
lua_unlock(L);
return i;
}
@@ -292,26 +288,37 @@ LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
- TObject n;
- const TObject *o = luaA_indexAcceptable(L, idx);
- if (o != NULL && tonumber(o, &n))
+ TValue n;
+ const TValue *o = luaA_index(L, idx);
+ if (tonumber(o, &n))
return nvalue(o);
else
return 0;
}
+LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
+ TValue n;
+ const TValue *o = luaA_index(L, idx);
+ if (tonumber(o, &n)) {
+ lua_Integer res;
+ lua_number2integer(res, nvalue(o));
+ return res;
+ }
+ else
+ return 0;
+}
+
+
LUA_API int lua_toboolean (lua_State *L, int idx) {
- const TObject *o = luaA_indexAcceptable(L, idx);
- return (o != NULL) && !l_isfalse(o);
+ const TValue *o = luaA_index(L, idx);
+ return !l_isfalse(o);
}
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))
+ StkId o = luaA_index(L, idx);
+ if (ttisstring(o))
return svalue(o);
else {
const char *s;
@@ -325,15 +332,13 @@ LUA_API const char *lua_tostring (lua_State *L, int idx) {
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))
- return tsvalue(o)->tsv.len;
+ StkId o = luaA_index(L, idx);
+ if (ttisstring(o))
+ return tsvalue(o)->len;
else {
size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */
- l = (luaV_tostring(L, o) ? tsvalue(o)->tsv.len : 0);
+ l = (luaV_tostring(L, o) ? tsvalue(o)->len : 0);
lua_unlock(L);
return l;
}
@@ -341,16 +346,15 @@ LUA_API size_t lua_strlen (lua_State *L, int idx) {
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;
+ StkId o = luaA_index(L, idx);
+ return (!iscfunction(o)) ? NULL : clvalue(o)->c.f;
}
LUA_API void *lua_touserdata (lua_State *L, int idx) {
- StkId o = luaA_indexAcceptable(L, idx);
- if (o == NULL) return NULL;
+ StkId o = luaA_index(L, idx);
switch (ttype(o)) {
- case LUA_TUSERDATA: return (uvalue(o) + 1);
+ case LUA_TUSERDATA: return (rawuvalue(o) + 1);
case LUA_TLIGHTUSERDATA: return pvalue(o);
default: return NULL;
}
@@ -358,24 +362,21 @@ LUA_API void *lua_touserdata (lua_State *L, int idx) {
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);
+ StkId o = luaA_index(L, idx);
+ return (!ttisthread(o)) ? NULL : thvalue(o);
}
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, idx);
- default: return NULL;
- }
+ StkId o = luaA_index(L, idx);
+ 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, idx);
+ default: return NULL;
}
}
@@ -402,10 +403,18 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
}
+LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
+ lua_lock(L);
+ setnvalue(L->top, cast(lua_Number, n));
+ api_incr_top(L);
+ lua_unlock(L);
+}
+
+
LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
lua_lock(L);
luaC_checkGC(L);
- setsvalue2s(L->top, luaS_newlstr(L, s, len));
+ setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
api_incr_top(L);
lua_unlock(L);
}
@@ -452,8 +461,9 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
cl->c.f = fn;
L->top -= n;
while (n--)
- setobj2n(&cl->c.upvalue[n], L->top+n);
- setclvalue(L->top, cl);
+ setobj2n(L, &cl->c.upvalue[n], L->top+n);
+ setclvalue(L, L->top, cl);
+ lua_assert(iswhite(obj2gco(cl)));
api_incr_top(L);
lua_unlock(L);
}
@@ -485,7 +495,21 @@ LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = luaA_index(L, idx);
- setobj2s(L->top - 1, luaV_gettable(L, t, L->top - 1, 0));
+ api_checkvalidindex(L, t);
+ luaV_gettable(L, t, L->top - 1, L->top - 1);
+ lua_unlock(L);
+}
+
+
+LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
+ StkId t;
+ TValue key;
+ lua_lock(L);
+ t = luaA_index(L, idx);
+ api_checkvalidindex(L, t);
+ setsvalue(L, &key, luaS_new(L, k));
+ luaV_gettable(L, t, &key, L->top);
+ api_incr_top(L);
lua_unlock(L);
}
@@ -495,7 +519,7 @@ LUA_API void lua_rawget (lua_State *L, int idx) {
lua_lock(L);
t = luaA_index(L, idx);
api_check(L, ttistable(t));
- setobj2s(L->top - 1, luaH_get(hvalue(t), L->top - 1));
+ setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
lua_unlock(L);
}
@@ -505,41 +529,39 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
lua_lock(L);
o = luaA_index(L, idx);
api_check(L, ttistable(o));
- setobj2s(L->top, luaH_getnum(hvalue(o), n));
+ setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
api_incr_top(L);
lua_unlock(L);
}
-LUA_API void lua_newtable (lua_State *L) {
+LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
lua_lock(L);
luaC_checkGC(L);
- sethvalue(L->top, luaH_new(L, 0, 0));
+ sethvalue(L, L->top, luaH_new(L, narray, luaO_log2(nrec) + 1));
api_incr_top(L);
lua_unlock(L);
}
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
- const TObject *obj;
+ const TValue *obj;
Table *mt = NULL;
int res;
lua_lock(L);
- obj = luaA_indexAcceptable(L, objindex);
- if (obj != NULL) {
- switch (ttype(obj)) {
- case LUA_TTABLE:
- mt = hvalue(obj)->metatable;
- break;
- case LUA_TUSERDATA:
- mt = uvalue(obj)->uv.metatable;
- break;
- }
+ obj = luaA_index(L, objindex);
+ switch (ttype(obj)) {
+ case LUA_TTABLE:
+ mt = hvalue(obj)->metatable;
+ break;
+ case LUA_TUSERDATA:
+ mt = uvalue(obj)->metatable;
+ break;
}
- if (mt == NULL || mt == hvalue(defaultmeta(L)))
+ if (mt == NULL)
res = 0;
else {
- sethvalue(L->top, mt);
+ sethvalue(L, L->top, mt);
api_incr_top(L);
res = 1;
}
@@ -552,7 +574,8 @@ LUA_API void lua_getfenv (lua_State *L, int idx) {
StkId o;
lua_lock(L);
o = luaA_index(L, idx);
- setobj2s(L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
+ api_checkvalidindex(L, o);
+ setobj2s(L, L->top, isLfunction(o) ? &clvalue(o)->l.g : gt(L));
api_incr_top(L);
lua_unlock(L);
}
@@ -568,19 +591,35 @@ LUA_API void lua_settable (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 2);
t = luaA_index(L, idx);
+ api_checkvalidindex(L, t);
luaV_settable(L, t, L->top - 2, L->top - 1);
L->top -= 2; /* pop index and value */
lua_unlock(L);
}
+LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
+ StkId t;
+ TValue key;
+ lua_lock(L);
+ api_checknelems(L, 1);
+ t = luaA_index(L, idx);
+ api_checkvalidindex(L, t);
+ setsvalue(L, &key, luaS_new(L, k));
+ luaV_settable(L, t, &key, L->top - 1);
+ L->top--; /* pop value */
+ lua_unlock(L);
+}
+
+
LUA_API void lua_rawset (lua_State *L, int idx) {
StkId t;
lua_lock(L);
api_checknelems(L, 2);
t = luaA_index(L, idx);
api_check(L, ttistable(t));
- setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */
+ setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
+ luaC_barrier(L, hvalue(t), L->top-1);
L->top -= 2;
lua_unlock(L);
}
@@ -592,27 +631,38 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
api_checknelems(L, 1);
o = luaA_index(L, idx);
api_check(L, ttistable(o));
- setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */
+ setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
+ luaC_barrier(L, hvalue(o), L->top-1);
L->top--;
lua_unlock(L);
}
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
- TObject *obj, *mt;
+ TValue *obj;
+ Table *mt;
int res = 1;
lua_lock(L);
api_checknelems(L, 1);
obj = luaA_index(L, objindex);
- mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
- api_check(L, ttistable(mt));
+ api_checkvalidindex(L, obj);
+ if (ttisnil(L->top - 1))
+ mt = NULL;
+ else {
+ api_check(L, ttistable(L->top - 1));
+ mt = hvalue(L->top - 1);
+ }
switch (ttype(obj)) {
case LUA_TTABLE: {
- hvalue(obj)->metatable = hvalue(mt); /* write barrier */
+ hvalue(obj)->metatable = mt;
+ if (mt)
+ luaC_objbarrier(L, hvalue(obj), mt);
break;
}
case LUA_TUSERDATA: {
- uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */
+ uvalue(obj)->metatable = mt;
+ if (mt)
+ luaC_objbarrier(L, rawuvalue(obj), mt);
break;
}
default: {
@@ -632,6 +682,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
lua_lock(L);
api_checknelems(L, 1);
o = luaA_index(L, idx);
+ api_checkvalidindex(L, o);
L->top--;
api_check(L, ttistable(L->top));
if (isLfunction(o)) {
@@ -679,7 +730,13 @@ LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
int status;
ptrdiff_t func;
lua_lock(L);
- func = (errfunc == 0) ? 0 : savestack(L, luaA_index(L, errfunc));
+ if (errfunc == 0)
+ func = 0;
+ else {
+ StkId o = luaA_index(L, errfunc);
+ api_checkvalidindex(L, o);
+ func = savestack(L, o);
+ }
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);
@@ -702,7 +759,7 @@ static void f_Ccall (lua_State *L, void *ud) {
Closure *cl;
cl = luaF_newCclosure(L, 0);
cl->c.f = c->func;
- setclvalue(L->top, cl); /* push function */
+ setclvalue(L, L->top, cl); /* push function */
incr_top(L);
setpvalue(L->top, c->ud); /* push only argument */
incr_top(L);
@@ -726,12 +783,10 @@ LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
const char *chunkname) {
ZIO z;
int status;
- int c;
lua_lock(L);
if (!chunkname) chunkname = "?";
- luaZ_init(&z, reader, data, chunkname);
- c = luaZ_lookahead(&z);
- status = luaD_protectedparser(L, &z, (c == LUA_SIGNATURE[0]));
+ luaZ_init(L, &z, reader, data);
+ status = luaD_protectedparser(L, &z, chunkname);
lua_unlock(L);
return status;
}
@@ -739,14 +794,12 @@ LUA_API int lua_load (lua_State *L, lua_Chunkreader reader, void *data,
LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
int status;
- TObject *o;
+ TValue *o;
lua_lock(L);
api_checknelems(L, 1);
o = L->top - 1;
- if (isLfunction(o) && clvalue(o)->l.nupvalues == 0) {
- luaU_dump(L, clvalue(o)->l.p, writer, data);
- status = 1;
- }
+ if (isLfunction(o))
+ status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
else
status = 0;
lua_unlock(L);
@@ -755,39 +808,34 @@ LUA_API int lua_dump (lua_State *L, lua_Chunkwriter writer, void *data) {
/*
-** Garbage-collection functions
+** Garbage-collection function
*/
-/* 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)
-
-LUA_API int lua_getgcthreshold (lua_State *L) {
- int threshold;
- lua_lock(L);
- threshold = GCscale(G(L)->GCthreshold);
- lua_unlock(L);
- return threshold;
+LUA_API int lua_gc (lua_State *L, int what, int data) {
+ global_State *g = G(L);
+ switch (what) {
+ case LUA_GCSTOP: {
+ g->GCthreshold = MAXLMEM;
+ return 0;
+ }
+ case LUA_GCRESTART: {
+ g->GCthreshold = g->nblocks;
+ return 0;
+ }
+ case LUA_GCCOLLECT: {
+ lua_lock(L);
+ luaC_fullgc(L);
+ lua_unlock(L);
+ return 0;
+ }
+ case LUA_GCCOUNT: {
+ /* GC values are expressed in Kbytes: #bytes/2^10 */
+ return cast(int, g->nblocks >> 10);
+ }
+ default: return -1; /* invalid option */
+ }
}
-LUA_API int lua_getgccount (lua_State *L) {
- int count;
- lua_lock(L);
- count = GCscale(G(L)->nblocks);
- lua_unlock(L);
- return count;
-}
-
-LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
- lua_lock(L);
- if (cast(lu_mem, newthreshold) > GCscalel(MAX_LUMEM))
- G(L)->GCthreshold = MAX_LUMEM;
- else
- G(L)->GCthreshold = GCunscale(newthreshold);
- luaC_checkGC(L);
- lua_unlock(L);
-}
/*
@@ -835,7 +883,7 @@ LUA_API void lua_concat (lua_State *L, int n) {
L->top -= (n-1);
}
else if (n == 0) { /* push empty string */
- setsvalue2s(L->top, luaS_newlstr(L, NULL, 0));
+ setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
api_incr_top(L);
}
/* else n == 1; nothing to do */
@@ -843,39 +891,28 @@ LUA_API void lua_concat (lua_State *L, int n) {
}
+LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
+ *ud = G(L)->ud;
+ return G(L)->realloc;
+}
+
+
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u;
lua_lock(L);
luaC_checkGC(L);
u = luaS_newudata(L, size);
- setuvalue(L->top, u);
+ setuvalue(L, L->top, u);
api_incr_top(L);
lua_unlock(L);
return u + 1;
}
-LUA_API int lua_pushupvalues (lua_State *L) {
- Closure *func;
- int n, i;
- lua_lock(L);
- api_check(L, iscfunction(L->base - 1));
- func = clvalue(L->base - 1);
- n = func->c.nupvalues;
- luaD_checkstack(L, n + LUA_MINSTACK);
- for (i=0; i<n; i++) {
- setobj2s(L->top, &func->c.upvalue[i]);
- L->top++;
- }
- lua_unlock(L);
- return n;
-}
-static const char *aux_upvalue (lua_State *L, int funcindex, int n,
- TObject **val) {
+static const char *aux_upvalue (lua_State *L, StkId fi, int n, TValue **val) {
Closure *f;
- StkId fi = luaA_index(L, funcindex);
if (!ttisfunction(fi)) return NULL;
f = clvalue(fi);
if (f->c.isC) {
@@ -894,11 +931,11 @@ static const char *aux_upvalue (lua_State *L, int funcindex, int n,
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
- TObject *val;
+ TValue *val;
lua_lock(L);
- name = aux_upvalue(L, funcindex, n, &val);
+ name = aux_upvalue(L, luaA_index(L, funcindex), n, &val);
if (name) {
- setobj2s(L->top, val);
+ setobj2s(L, L->top, val);
api_incr_top(L);
}
lua_unlock(L);
@@ -908,13 +945,16 @@ 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) {
const char *name;
- TObject *val;
+ TValue *val;
+ StkId fi;
lua_lock(L);
+ fi = luaA_index(L, funcindex);
api_checknelems(L, 1);
- name = aux_upvalue(L, funcindex, n, &val);
+ name = aux_upvalue(L, fi, n, &val);
if (name) {
L->top--;
- setobj(val, L->top); /* write barrier */
+ setobj(L, val, L->top);
+ luaC_barrier(L, clvalue(fi), L->top);
}
lua_unlock(L);
return name;