diff --git a/lapi.c b/lapi.c index 9d7a07ce..86e20807 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.86 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lapi.c,v 1.87 2000/08/14 19:10:14 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -16,7 +16,6 @@ #include "lgc.h" #include "lmem.h" #include "lobject.h" -#include "lref.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" @@ -29,246 +28,148 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n" -void luaA_checkCargs (lua_State *L, int nargs) { - if (nargs > L->top-L->Cstack.base) - luaL_verror(L, "Lua API error - " - "expected at least %d arguments in C2lua stack", nargs); +#define Index(L,i) ((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i))) + +#define api_incr_top(L) (++L->top) + + + + +TObject *luaA_index (lua_State *L, int index) { + return Index(L, index); } -lua_Object luaA_putluaObject (lua_State *L, const TObject *o) { - luaD_openstack(L, L->Cstack.base); - *L->Cstack.base++ = *o; - return L->Cstack.base-1; -} - - -static void top2LC (lua_State *L, int n) { - /* Put the `n' elements on the top as the Lua2C contents */ - L->Cstack.base = L->top; /* new base */ - L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */ - L->Cstack.num = n; /* number of results */ -} - - -lua_Object lua_pop (lua_State *L) { - luaA_checkCargs(L, 1); - if (L->Cstack.base != L->top-1) { - luaD_openstack(L, L->Cstack.base); - *L->Cstack.base = *(--L->top); - } - return L->Cstack.base++; -} - - -void lua_pushglobals (lua_State *L) { - hvalue(L->top) = L->gt; - ttype(L->top) = TAG_TABLE; +void luaA_pushobject (lua_State *L, const TObject *o) { + *L->top = *o; incr_top; } -void lua_setglobals (lua_State *L, lua_Object newtable) { - if (lua_type(L, newtable)[0] != 't') /* type == "table"? */ - lua_error(L, "Lua API error - invalid value for global table"); - L->gt = hvalue(newtable); + +/* +** basic stack manipulation +*/ + + +int lua_gettop (lua_State *L) { + return (L->top - L->Cbase); } +void lua_settop (lua_State *L, int index) { + if (index >= 0) + luaD_adjusttop(L, L->Cbase, index); + else + L->top += index; /* index is negative */ +} + + +void lua_pushobject (lua_State *L, int index) { + *L->top = *Index(L, index); + api_incr_top(L); +} + + + /* -** Get a parameter, returning the object handle or LUA_NOOBJECT on error. -** `number' must be 1 to get the first parameter. +** access functions (stack -> C) */ -lua_Object lua_lua2C (lua_State *L, int number) { - if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT; - return L->Cstack.lua2C+number-1; + + +#define btest(L,i,value,default) { \ + StkId o; \ + if ((i) >= 0) { \ + o = L->Cbase+((i)-1); \ + if (o >= L->top) return (default); \ + } \ + else o = L->top+(i); \ + return (value); } + + +#define access(L,i,test,default,value) { \ + StkId o; \ + if ((i) >= 0) { \ + o = L->Cbase+((i)-1); \ + if (o >= L->top) return (default); \ + } \ + else o = L->top+(i); \ + return ((test) ? (value) : (default)); } + + +const char *lua_type (lua_State *L, int index) { + btest(L, index, luaO_typename(o), "NO VALUE"); +} + +int lua_iscfunction (lua_State *L, int index) { + btest(L, index, (ttype(o) == TAG_CCLOSURE), 0); +} + +int lua_isnumber (lua_State *L, int index) { + btest(L, index, (tonumber(Index(L, index)) == 0), 0); +} + +int lua_tag (lua_State *L, int index) { + btest(L, index, + ((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : luaT_effectivetag(L, o)), + -1); +} + +int lua_equal(lua_State *L, int index1, int index2) { + return luaO_equalObj(Index(L, index1), Index(L, index2)); } -int lua_callfunction (lua_State *L, lua_Object function) { - if (function == LUA_NOOBJECT) - return 1; - else { - luaD_openstack(L, L->Cstack.base); - *L->Cstack.base = *function; - return luaD_protectedrun(L); - } + +double lua_tonumber (lua_State *L, int index) { + access(L, index, (tonumber(o) == 0), 0.0, nvalue(o)); } - -lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) { - return luaA_putluaObject(L, luaT_gettagmethod(L, tag, event)); -} - - -lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) { - TObject *method; - luaA_checkCargs(L, 1); - method = L->top-1; - if ((ttype(method) != TAG_NIL) && (*lua_type(L, method) != 'f')) - lua_error(L, "Lua API error - tag method must be a function or nil"); - luaT_settagmethod(L, tag, event, method); - return lua_pop(L); -} - - -lua_Object lua_gettable (lua_State *L) { - luaA_checkCargs(L, 2); - luaV_gettable(L, L->top--); - return lua_pop(L); -} - - -lua_Object lua_rawget (lua_State *L) { - lua_Object res; - luaA_checkCargs(L, 2); - if (ttype(L->top-2) != TAG_TABLE) - lua_error(L, "indexed expression not a table"); - res = luaA_putluaObject(L, luaH_get(L, hvalue(L->top-2), L->top-1)); - L->top -= 2; - return res; -} - - -void lua_settable (lua_State *L) { - StkId top; - luaA_checkCargs(L, 3); - top = L->top; - luaV_settable(L, top-3, top); - L->top = top-3; /* pop table, index, and value */ -} - - -void lua_rawset (lua_State *L) { - luaA_checkCargs(L, 3); - if (ttype(L->top-3) != TAG_TABLE) - lua_error(L, "indexed expression not a table"); - *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); - L->top -= 3; -} - - -lua_Object lua_createtable (lua_State *L) { - TObject o; - luaC_checkGC(L); - hvalue(&o) = luaH_new(L, 0); - ttype(&o) = TAG_TABLE; - return luaA_putluaObject(L, &o); -} - - -lua_Object lua_getglobal (lua_State *L, const char *name) { - luaV_getglobal(L, luaS_new(L, name), L->top++); - return lua_pop(L); -} - - -void lua_setglobal (lua_State *L, const char *name) { - luaA_checkCargs(L, 1); - luaV_setglobal(L, luaS_new(L, name), L->top--); -} - - -const char *lua_type (lua_State *L, lua_Object o) { - UNUSED(L); - return (o == LUA_NOOBJECT) ? "NOOBJECT" : luaO_typename(o); -} - -int lua_isnil (lua_State *L, lua_Object o) { - UNUSED(L); - return (o != LUA_NOOBJECT) && (ttype(o) == TAG_NIL); -} - -int lua_istable (lua_State *L, lua_Object o) { - UNUSED(L); - return (o != LUA_NOOBJECT) && (ttype(o) == TAG_TABLE); -} - -int lua_isuserdata (lua_State *L, lua_Object o) { - UNUSED(L); - return (o != LUA_NOOBJECT) && (ttype(o) == TAG_USERDATA); -} - -int lua_iscfunction (lua_State *L, lua_Object o) { - UNUSED(L); - return (o != LUA_NOOBJECT) && (ttype(o) == TAG_CCLOSURE); -} - -int lua_isnumber (lua_State *L, lua_Object o) { - UNUSED(L); - return (o != LUA_NOOBJECT) && (tonumber(o) == 0); -} - -int lua_isstring (lua_State *L, lua_Object o) { - UNUSED(L); - return (o != LUA_NOOBJECT && (ttype(o) == TAG_STRING || - ttype(o) == TAG_NUMBER)); -} - -int lua_isfunction (lua_State *L, lua_Object o) { - return *lua_type(L, o) == 'f'; -} - -int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) { - UNUSED(L); - if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT) - return (o1 == o2); - else return luaO_equalObj(o1, o2); -} - - -double lua_getnumber (lua_State *L, lua_Object obj) { - UNUSED(L); - if (obj == LUA_NOOBJECT || tonumber(obj)) - return 0.0; - else return (nvalue(obj)); -} - -const char *lua_getstring (lua_State *L, lua_Object obj) { +const char *lua_tostring (lua_State *L, int index) { luaC_checkGC(L); /* `tostring' may create a new string */ - if (obj == LUA_NOOBJECT || tostring(L, obj)) - return NULL; - else return (svalue(obj)); + access(L, index, (tostring(L, o) == 0), NULL, svalue(o)); } -size_t lua_strlen (lua_State *L, lua_Object obj) { - if (obj == LUA_NOOBJECT || tostring(L, obj)) - return 0L; - else return (tsvalue(obj)->u.s.len); +size_t lua_strlen (lua_State *L, int index) { + access(L, index, (tostring(L, o) == 0), 0, tsvalue(o)->u.s.len); } -void *lua_getuserdata (lua_State *L, lua_Object obj) { - UNUSED(L); - if (obj == LUA_NOOBJECT || ttype(obj) != TAG_USERDATA) - return NULL; - else return tsvalue(obj)->u.d.value; +lua_CFunction lua_tocfunction (lua_State *L, int index) { + access(L, index, (ttype(o) == TAG_CCLOSURE), NULL, clvalue(o)->f.c); } -lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) { - if (!lua_iscfunction(L, obj)) - return NULL; - else return clvalue(obj)->f.c; +void *lua_touserdata (lua_State *L, int index) { + access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value); } + +/* +** push functions (C -> stack) +*/ + + void lua_pushnil (lua_State *L) { ttype(L->top) = TAG_NIL; - incr_top; + api_incr_top(L); } + void lua_pushnumber (lua_State *L, double n) { ttype(L->top) = TAG_NUMBER; nvalue(L->top) = n; - incr_top; + api_incr_top(L); } + void lua_pushlstring (lua_State *L, const char *s, size_t len) { + luaC_checkGC(L); tsvalue(L->top) = luaS_newlstr(L, s, len); ttype(L->top) = TAG_STRING; - incr_top; - luaC_checkGC(L); + api_incr_top(L); } + void lua_pushstring (lua_State *L, const char *s) { if (s == NULL) lua_pushnil(L); @@ -276,48 +177,154 @@ void lua_pushstring (lua_State *L, const char *s) { lua_pushlstring(L, s, strlen(s)); } + void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { - if (fn == NULL) - lua_error(L, "Lua API error - attempt to push a NULL Cfunction"); - luaA_checkCargs(L, n); - luaV_Cclosure(L, fn, n); luaC_checkGC(L); + luaV_Cclosure(L, fn, n); } + void lua_pushusertag (lua_State *L, void *u, int tag) { /* ORDER LUA_T */ + luaC_checkGC(L); if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS) luaL_verror(L, "invalid tag for a userdata (%d)", tag); tsvalue(L->top) = luaS_createudata(L, u, tag); ttype(L->top) = TAG_USERDATA; - incr_top; - luaC_checkGC(L); -} - -void luaA_pushobject (lua_State *L, const TObject *o) { - *L->top = *o; - incr_top; -} - -void lua_pushobject (lua_State *L, lua_Object o) { - if (o == LUA_NOOBJECT) - lua_error(L, "Lua API error - attempt to push a NOOBJECT"); - *L->top = *o; - incr_top; + api_incr_top(L); } -int lua_tag (lua_State *L, lua_Object o) { - if (o == LUA_NOOBJECT) - return TAG_NIL; - else if (ttype(o) == TAG_USERDATA) /* to allow `old' tags (deprecated) */ - return tsvalue(o)->u.d.tag; + +/* +** get functions (Lua -> stack) +*/ + + +void lua_getglobal (lua_State *L, const char *name) { + luaV_getglobal(L, luaS_new(L, name), L->top++); +} + + +void lua_gettable (lua_State *L) { + luaV_gettable(L, L->top--); +} + + +void lua_rawget (lua_State *L) { + if (ttype(L->top - 2) != TAG_TABLE) + lua_error(L, "indexed expression not a table"); + *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1); + L->top--; +} + + +void lua_getglobals (lua_State *L) { + hvalue(L->top) = L->gt; + ttype(L->top) = TAG_TABLE; + api_incr_top(L); +} + + +void lua_gettagmethod (lua_State *L, int tag, const char *event) { + *L->top = *luaT_gettagmethod(L, tag, event); + api_incr_top(L); +} + + +int lua_getref (lua_State *L, int ref) { + if (ref == LUA_REFNIL) + ttype(L->top) = TAG_NIL; + else if (0 <= ref && ref < L->refSize && + (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD)) + *L->top = L->refArray[ref].o; else - return luaT_effectivetag(L, o); + return 0; + api_incr_top(L); + return 1; } +void lua_newtable (lua_State *L) { + luaC_checkGC(L); + hvalue(L->top) = luaH_new(L, 0); + ttype(L->top) = TAG_TABLE; + api_incr_top(L); +} + + + +/* +** set functions (stack -> Lua) +*/ + + +void lua_setglobal (lua_State *L, const char *name) { + luaV_setglobal(L, luaS_new(L, name), L->top--); +} + + +void lua_settable (lua_State *L) { + StkId top = L->top; + luaV_settable(L, top-3, top); + L->top = top-3; /* pop table, index, and value */ +} + + +void lua_rawset (lua_State *L) { + if (ttype(L->top-3) != TAG_TABLE) + lua_error(L, "indexed expression not a table"); + *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1); + L->top -= 3; +} + + +void lua_setglobals (lua_State *L) { + TObject *newtable = --L->top; + if (ttype(newtable) != TAG_TABLE) + lua_error(L, "Lua API error - invalid value for global table"); + L->gt = hvalue(newtable); +} + + +void lua_settagmethod (lua_State *L, int tag, const char *event) { + TObject *method = L->top - 1; + if (ttype(method) != TAG_NIL && + ttype(method) != TAG_CCLOSURE && + ttype(method) != TAG_LCLOSURE) + lua_error(L, "Lua API error - tag method must be a function or nil"); + luaT_settagmethod(L, tag, event, method); +} + + +int lua_ref (lua_State *L, int lock) { + int ref; + if (ttype(L->top-1) == TAG_NIL) + ref = LUA_REFNIL; + else { + if (L->refFree != NONEXT) { /* is there a free place? */ + ref = L->refFree; + L->refFree = L->refArray[ref].st; + } + else { /* no more free places */ + luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref, + "reference table overflow", MAX_INT); + ref = L->refSize++; + } + L->refArray[ref].o = *(L->top-1); + L->refArray[ref].st = lock ? LOCK : HOLD; + } + L->top--; + return ref; +} + + + +/* +** miscelaneous functions +*/ + + void lua_settag (lua_State *L, int tag) { - luaA_checkCargs(L, 1); luaT_realtag(L, tag); switch (ttype(L->top-1)) { case TAG_TABLE: @@ -334,6 +341,17 @@ void lua_settag (lua_State *L, int tag) { } +void lua_unref (lua_State *L, int ref) { + if (ref >= 0) { + if (ref >= L->refSize || L->refArray[ref].st >= 0) + lua_error(L, "Lua API error - " + "invalid argument for function `lua_unref'"); + L->refArray[ref].st = L->refFree; + L->refFree = ref; + } +} + + int luaA_next (lua_State *L, const Hash *t, int i) { int tsize = t->size; for (; isize; @@ -73,7 +72,8 @@ static Number getnarg (lua_State *L, const Hash *a) { static Hash *gettable (lua_State *L, int arg) { - return hvalue(luaL_tablearg(L, arg)); + luaL_checktype(L, arg, "table"); + return hvalue(luaA_index(L, arg)); } /* }====================================================== */ @@ -90,8 +90,9 @@ static Hash *gettable (lua_State *L, int arg) { ** If your system does not support `stderr', redefine this function, or ** redefine _ERRORMESSAGE so that it won't need _ALERT. */ -void luaB__ALERT (lua_State *L) { +int luaB__ALERT (lua_State *L) { fputs(luaL_check_string(L, 1), stderr); + return 0; } @@ -99,18 +100,19 @@ void luaB__ALERT (lua_State *L) { ** Standard implementation of _ERRORMESSAGE. ** The library `liolib' redefines _ERRORMESSAGE for better error information. */ -void luaB__ERRORMESSAGE (lua_State *L) { - lua_Object al; - lua_pushglobals(L); +int luaB__ERRORMESSAGE (lua_State *L) { + lua_getglobals(L); lua_pushstring(L, LUA_ALERT); - al = lua_rawget(L); - if (lua_isfunction(L, al)) { /* avoid error loop if _ALERT is not defined */ + lua_rawget(L); + if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ const char *s = luaL_check_string(L, 1); char *buff = luaL_openspace(L, strlen(s)+sizeof("error: \n")); strcpy(buff, "error: "); strcat(buff, s); strcat(buff, "\n"); + lua_pushobject(L, -1); /* function to be called */ lua_pushstring(L, buff); - lua_callfunction(L, al); + lua_call(L, 1, 0); } + return 0; } @@ -120,36 +122,35 @@ void luaB__ERRORMESSAGE (lua_State *L) { ** model but changing `fputs' to put the strings at a proper place ** (a console window or a log file, for instance). */ -void luaB_print (lua_State *L) { - lua_Object args[MAXPRINT]; - lua_Object obj; - int n = 0; +int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ int i; - while ((obj = lua_getparam(L, n+1)) != LUA_NOOBJECT) { - luaL_arg_check(L, n < MAXPRINT, n+1, "too many arguments"); - args[n++] = obj; - } - for (i=0; i0) fputs("\t", stdout); - fputs(lua_getstring(L, obj), stdout); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_settop(L, -1); /* pop result */ } fputs("\n", stdout); + return 0; } -void luaB_tonumber (lua_State *L) { +int luaB_tonumber (lua_State *L) { int base = luaL_opt_int(L, 2, 10); if (base == 10) { /* standard conversion */ - lua_Object o = luaL_nonnullarg(L, 1); - if (lua_isnumber(L, o)) { - lua_pushnumber(L, lua_getnumber(L, o)); - return; + luaL_checktype(L, 1, "any"); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; } } else { @@ -162,94 +163,108 @@ void luaB_tonumber (lua_State *L) { while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */ if (*s2 == '\0') { /* no invalid trailing characters? */ lua_pushnumber(L, n); - return; + return 1; } } } lua_pushnil(L); /* else not a number */ + return 1; } -void luaB_error (lua_State *L) { +int luaB_error (lua_State *L) { lua_error(L, luaL_opt_string(L, 1, NULL)); + return 0; /* to avoid errors */ } -void luaB_setglobal (lua_State *L) { - const char *name = luaL_check_string(L, 1); - lua_Object value = luaL_nonnullarg(L, 2); - lua_pushobject(L, value); - lua_setglobal(L, name); +int luaB_setglobal (lua_State *L) { + luaL_checktype(L, 2, "any"); + lua_setglobal(L, luaL_check_string(L, 1)); + return 0; } -void luaB_getglobal (lua_State *L) { - lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1))); +int luaB_getglobal (lua_State *L) { + lua_getglobal(L, luaL_check_string(L, 1)); + return 1; } -void luaB_tag (lua_State *L) { - lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1))); +int luaB_tag (lua_State *L) { + luaL_checktype(L, 1, "any"); + lua_pushnumber(L, lua_tag(L, 1)); + return 1; } -void luaB_settag (lua_State *L) { - lua_Object o = luaL_tablearg(L, 1); - lua_pushobject(L, o); +int luaB_settag (lua_State *L) { + luaL_checktype(L, 1, "table"); + lua_pushobject(L, 1); /* push table */ lua_settag(L, luaL_check_int(L, 2)); - lua_pushobject(L, o); /* return first argument */ + lua_pushobject(L, 1); /* return first argument */ + return 1; } -void luaB_newtag (lua_State *L) { +int luaB_newtag (lua_State *L) { lua_pushnumber(L, lua_newtag(L)); + return 1; } -void luaB_copytagmethods (lua_State *L) { +int luaB_copytagmethods (lua_State *L) { lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1), luaL_check_int(L, 2))); + return 1; } -void luaB_globals (lua_State *L) { - lua_pushglobals(L); - if (lua_getparam(L, 1) != LUA_NOOBJECT) - lua_setglobals(L, luaL_tablearg(L, 1)); +int luaB_globals (lua_State *L) { + lua_getglobals(L); /* value to be returned */ + if (!lua_isnull(L, 1)) { + luaL_checktype(L, 1, "table"); + lua_pushobject(L, 1); /* new table of globals */ + lua_setglobals(L); + } + return 1; } -void luaB_rawget (lua_State *L) { - lua_pushobject(L, luaL_nonnullarg(L, 1)); - lua_pushobject(L, luaL_nonnullarg(L, 2)); - lua_pushobject(L, lua_rawget(L)); +int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, "table"); + luaL_checktype(L, 2, "any"); + lua_rawget(L); + return 1; } -void luaB_rawset (lua_State *L) { - lua_pushobject(L, luaL_nonnullarg(L, 1)); - lua_pushobject(L, luaL_nonnullarg(L, 2)); - lua_pushobject(L, luaL_nonnullarg(L, 3)); +int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, "table"); + luaL_checktype(L, 2, "any"); + luaL_checktype(L, 3, "any"); lua_rawset(L); + return 1; } -void luaB_settagmethod (lua_State *L) { - int tag = luaL_check_int(L, 1); +int luaB_settagmethod (lua_State *L) { + int tag = (int)luaL_check_int(L, 1); const char *event = luaL_check_string(L, 2); - lua_Object nf = luaL_nonnullarg(L, 3); - luaL_arg_check(L, lua_isnil(L, nf) || lua_isfunction(L, nf), 3, + luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3, "function or nil expected"); if (strcmp(event, "gc") == 0 && tag != TAG_NIL) lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); - lua_pushobject(L, nf); - lua_pushobject(L, lua_settagmethod(L, tag, event)); + lua_settagmethod(L, tag, event); + return 1; } -void luaB_gettagmethod (lua_State *L) { - lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1), - luaL_check_string(L, 2))); +int luaB_gettagmethod (lua_State *L) { + lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2)); + return 1; } -void luaB_collectgarbage (lua_State *L) { +int luaB_collectgarbage (lua_State *L) { lua_pushnumber(L, lua_collectgarbage(L, luaL_opt_int(L, 1, 0))); + return 1; } -void luaB_type (lua_State *L) { - lua_Object o = luaL_nonnullarg(L, 1); - lua_pushstring(L, lua_type(L, o)); +int luaB_type (lua_State *L) { + luaL_checktype(L, 1, "any"); + lua_pushstring(L, lua_type(L, 1)); + return 1; } /* }====================================================== */ @@ -263,99 +278,115 @@ void luaB_type (lua_State *L) { */ -static void passresults (lua_State *L) { - L->Cstack.base = L->Cstack.lua2C; /* position of first result */ - if (L->Cstack.num == 0) - lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ +static int passresults (lua_State *L, int status, int oldtop) { + if (status == 0) { + int nresults = lua_gettop(L) - oldtop; + if (nresults > 0) + return nresults; /* results are already on the stack */ + else { + lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ + return 1; + } + } + else { /* error */ + lua_pushnil(L); + lua_pushnumber(L, status); /* error code */ + return 2; + } } -void luaB_dostring (lua_State *L) { +int luaB_dostring (lua_State *L) { + int oldtop = lua_gettop(L); size_t l; const char *s = luaL_check_lstr(L, 1, &l); if (*s == ID_CHUNK) lua_error(L, "`dostring' cannot run pre-compiled code"); - if (lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)) == 0) - passresults(L); - else - lua_pushnil(L); + return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop); } -void luaB_dofile (lua_State *L) { +int luaB_dofile (lua_State *L) { + int oldtop = lua_gettop(L); const char *fname = luaL_opt_string(L, 1, NULL); - if (lua_dofile(L, fname) == 0) - passresults(L); - else - lua_pushnil(L); + return passresults(L, lua_dofile(L, fname), oldtop); } -void luaB_call (lua_State *L) { - lua_Object f = luaL_nonnullarg(L, 1); +int luaB_call (lua_State *L) { + int oldtop; const Hash *arg = gettable(L, 2); const char *options = luaL_opt_string(L, 3, ""); - lua_Object err = lua_getparam(L, 4); - int narg = (int)getnarg(L, arg); + int err = 0; /* index of old error method */ + int n = (int)getnarg(L, arg); int i, status; - if (err != LUA_NOOBJECT) { /* set new error method */ - lua_Object oldem = lua_getglobal(L, LUA_ERRORMESSAGE); - lua_pushobject(L, err); + if (!lua_isnull(L, 4)) { /* set new error method */ + lua_getglobal(L, LUA_ERRORMESSAGE); + err = lua_gettop(L); /* get index */ + lua_pushobject(L, 4); lua_setglobal(L, LUA_ERRORMESSAGE); - err = oldem; } + oldtop = lua_gettop(L); /* top before function-call preparation */ + /* push function */ + lua_pushobject(L, 1); /* push arg[1...n] */ - luaD_checkstack(L, narg); - for (i=0; itop++) = *luaH_getnum(arg, i+1); - status = lua_callfunction(L, f); - if (err != LUA_NOOBJECT) { /* restore old error method */ + status = lua_call(L, n, LUA_MULTRET); + n = lua_gettop(L) - oldtop; /* number of results */ + if (err != 0) { /* restore old error method */ lua_pushobject(L, err); lua_setglobal(L, LUA_ERRORMESSAGE); } if (status != 0) { /* error in call? */ - if (strchr(options, 'x')) { - lua_pushnil(L); - return; /* return nil to signal the error */ - } + if (strchr(options, 'x')) + lua_pushnil(L); /* return nil to signal the error */ else lua_error(L, NULL); /* propagate error without additional messages */ + return 1; } else { /* no errors */ if (strchr(options, 'p')) { /* pack results? */ - luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top); + luaV_pack(L, luaA_index(L, oldtop+1), n, L->top); incr_top; + return 1; /* only table is returned */ } else - L->Cstack.base = L->Cstack.lua2C; /* position of first result */ + return n; /* results are already on the stack */ } } -void luaB_next (lua_State *L) { +int luaB_next (lua_State *L) { const Hash *a = gettable(L, 1); - lua_Object k = lua_getparam(L, 2); int i; /* `luaA_next' gets first element after `i' */ - if (k == LUA_NOOBJECT || ttype(k) == TAG_NIL) + if (lua_isnull(L, 2) || lua_isnil(L, 2)) /* no index or nil index? */ i = 0; /* get first */ else { - i = luaH_pos(L, a, k)+1; + i = luaH_pos(L, a, luaA_index(L, 2))+1; luaL_arg_check(L, i != 0, 2, "key not found"); } - if (luaA_next(L, a, i) == 0) + if (luaA_next(L, a, i) != 0) + return 2; /* `luaA_next' left them on the stack */ + else { lua_pushnil(L); + return 1; + } } -void luaB_tostring (lua_State *L) { - lua_Object o = luaL_nonnullarg(L, 1); +int luaB_tostring (lua_State *L) { char buff[64]; + const TObject *o; + luaL_checktype(L, 1, "any"); + o = luaA_index(L, 1); switch (ttype(o)) { case TAG_NUMBER: - lua_pushstring(L, lua_getstring(L, o)); - return; + lua_pushstring(L, lua_tostring(L, 1)); + return 1; case TAG_STRING: - lua_pushobject(L, o); - return; + lua_pushobject(L, 1); + return 1; case TAG_TABLE: sprintf(buff, "table: %p", hvalue(o)); break; @@ -368,11 +399,12 @@ void luaB_tostring (lua_State *L) { break; case TAG_NIL: lua_pushstring(L, "nil"); - return; + return 1; default: LUA_INTERNALERROR("invalid type"); } lua_pushstring(L, buff); + return 1; } /* }====================================================== */ @@ -389,15 +421,17 @@ void luaB_tostring (lua_State *L) { ** ======================================================= */ -void luaB_assert (lua_State *L) { - lua_Object p = luaL_nonnullarg(L, 1); - if (lua_isnil(L, p)) +int luaB_assert (lua_State *L) { + luaL_checktype(L, 1, "any"); + if (lua_isnil(L, 1)) luaL_verror(L, "assertion failed! %.90s", luaL_opt_string(L, 2, "")); + return 0; } -void luaB_getn (lua_State *L) { +int luaB_getn (lua_State *L) { lua_pushnumber(L, getnarg(L, gettable(L, 1))); + return 1; } @@ -408,72 +442,72 @@ static void t_move (lua_State *L, Hash *t, int from, int to) { } -void luaB_tinsert (lua_State *L) { +int luaB_tinsert (lua_State *L) { Hash *a = gettable(L, 1); - lua_Object v = lua_getparam(L, 3); int n = (int)getnarg(L, a); + int v = lua_gettop(L); /* last argument: to be inserted */ int pos; - if (v != LUA_NOOBJECT) - pos = luaL_check_int(L, 2); - else { /* called with only 2 arguments */ - v = luaL_nonnullarg(L, 2); + if (v == 2) /* called with only 2 arguments */ pos = n+1; - } + else + pos = luaL_check_int(L, 2); /* 2nd argument is the position */ luaH_setstrnum(L, a, luaS_new(L, "n"), n+1); /* a.n = n+1 */ for (; n>=pos; n--) t_move(L, a, n, n+1); /* a[n+1] = a[n] */ - *luaH_setint(L, a, pos) = *v; /* a[pos] = v */ + *luaH_setint(L, a, pos) = *luaA_index(L, v); /* a[pos] = v */ + return 0; } -void luaB_tremove (lua_State *L) { +int luaB_tremove (lua_State *L) { Hash *a = gettable(L, 1); int n = (int)getnarg(L, a); int pos = luaL_opt_int(L, 2, n); - if (n <= 0) return; /* table is "empty" */ + if (n <= 0) return 0; /* table is "empty" */ luaA_pushobject(L, luaH_getnum(a, pos)); /* result = a[pos] */ for ( ;postop++) = *f; + lua_pushobject(L, 2); ttype(L->top) = TAG_NUMBER; nvalue(L->top++) = i; *(L->top++) = *luaH_getnum(t, i); luaD_call(L, L->top-3, 1); if (ttype(L->top-1) != TAG_NIL) - return; + return 1; L->top--; /* remove nil result */ } + return 0; } -static void luaB_foreach (lua_State *L) { +static int luaB_foreach (lua_State *L) { const Hash *a = gettable(L, 1); - lua_Object f = luaL_functionarg(L, 2); int i; - luaD_checkstack(L, 3); /* for f, key, and val */ + luaL_checktype(L, 2, "function"); for (i=0; isize; i++) { const Node *nd = &(a->node[i]); if (ttype(val(nd)) != TAG_NIL) { - *(L->top++) = *f; + lua_pushobject(L, 2); *(L->top++) = *key(nd); *(L->top++) = *val(nd); luaD_call(L, L->top-3, 1); if (ttype(L->top-1) != TAG_NIL) - return; + return 1; L->top--; /* remove result */ } } + return 0; } @@ -492,10 +526,10 @@ static void swap (lua_State *L, Hash *a, int i, int j) { *luaH_setint(L, a, j) = temp; } -static int sort_comp (lua_State *L, lua_Object f, const TObject *a, - const TObject *b) { +static int sort_comp (lua_State *L, const TObject *f, const TObject *a, + const TObject *b) { /* WARNING: the caller (auxsort) must ensure stack space */ - if (f != LUA_NOOBJECT) { + if (f != NULL) { *(L->top) = *f; *(L->top+1) = *a; *(L->top+2) = *b; @@ -508,7 +542,7 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a, return luaV_lessthan(L, a, b, L->top); } -static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { +static void auxsort (lua_State *L, Hash *a, int l, int u, const TObject *f) { StkId P = L->top++; /* temporary place for pivot */ ttype(P) = TAG_NIL; while (l < u) { /* for tail recursion */ @@ -552,14 +586,16 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { L->top--; /* remove pivot from stack */ } -void luaB_sort (lua_State *L) { +int luaB_sort (lua_State *L) { Hash *a = gettable(L, 1); int n = (int)getnarg(L, a); - lua_Object func = lua_getparam(L, 2); - luaL_arg_check(L, func == LUA_NOOBJECT || lua_isfunction(L, func), 2, - "function expected"); - luaD_checkstack(L, 4); /* for pivot, f, a, b (sort_comp) */ + const TObject *func = NULL; + if (!lua_isnull(L, 2)) { /* is there a 2nd argument? */ + luaL_checktype(L, 2, "function"); + func = luaA_index(L, 2); + } auxsort(L, a, 1, n, func); + return 0; } /* }====================================================== */ @@ -615,8 +651,9 @@ static void deprecated_funcs (lua_State *L) { /* ** gives an explicit error in any attempt to call a deprecated function */ -static void deprecated_func (lua_State *L) { +static int deprecated_func (lua_State *L) { luaL_verror(L, "function `%.20s' is deprecated", luaL_check_string(L, 1)); + return 0; /* to avoid warnings */ } diff --git a/lbuiltin.h b/lbuiltin.h index 213f3f3d..7d8a2236 100644 --- a/lbuiltin.h +++ b/lbuiltin.h @@ -1,5 +1,5 @@ /* -** $Id: lbuiltin.h,v 1.8 2000/05/08 19:32:53 roberto Exp roberto $ +** $Id: lbuiltin.h,v 1.9 2000/05/26 19:17:57 roberto Exp roberto $ ** Built-in functions ** See Copyright Notice in lua.h */ @@ -9,34 +9,34 @@ #include "lua.h" -void luaB__ALERT (lua_State *L); -void luaB__ERRORMESSAGE (lua_State *L); -void luaB_assert (lua_State *L); -void luaB_call (lua_State *L); -void luaB_collectgarbage (lua_State *L); -void luaB_copytagmethods (lua_State *L); -void luaB_dofile (lua_State *L); -void luaB_dostring (lua_State *L); -void luaB_error (lua_State *L); -void luaB_getglobal (lua_State *L); -void luaB_getn (lua_State *L); -void luaB_gettagmethod (lua_State *L); -void luaB_globals (lua_State *L); -void luaB_newtag (lua_State *L); -void luaB_next (lua_State *L); -void luaB_print (lua_State *L); -void luaB_rawget (lua_State *L); -void luaB_rawset (lua_State *L); -void luaB_setglobal (lua_State *L); -void luaB_settag (lua_State *L); -void luaB_settagmethod (lua_State *L); -void luaB_sort (lua_State *L); -void luaB_tag (lua_State *L); -void luaB_tinsert (lua_State *L); -void luaB_tonumber (lua_State *L); -void luaB_tostring (lua_State *L); -void luaB_tremove (lua_State *L); -void luaB_type (lua_State *L); +int luaB__ALERT (lua_State *L); +int luaB__ERRORMESSAGE (lua_State *L); +int luaB_assert (lua_State *L); +int luaB_call (lua_State *L); +int luaB_collectgarbage (lua_State *L); +int luaB_copytagmethods (lua_State *L); +int luaB_dofile (lua_State *L); +int luaB_dostring (lua_State *L); +int luaB_error (lua_State *L); +int luaB_getglobal (lua_State *L); +int luaB_getn (lua_State *L); +int luaB_gettagmethod (lua_State *L); +int luaB_globals (lua_State *L); +int luaB_newtag (lua_State *L); +int luaB_next (lua_State *L); +int luaB_print (lua_State *L); +int luaB_rawget (lua_State *L); +int luaB_rawset (lua_State *L); +int luaB_setglobal (lua_State *L); +int luaB_settag (lua_State *L); +int luaB_settagmethod (lua_State *L); +int luaB_sort (lua_State *L); +int luaB_tag (lua_State *L); +int luaB_tinsert (lua_State *L); +int luaB_tonumber (lua_State *L); +int luaB_tostring (lua_State *L); +int luaB_tremove (lua_State *L); +int luaB_type (lua_State *L); void luaB_predefine (lua_State *L); diff --git a/ldblib.c b/ldblib.c index 45edc8c2..17edcda5 100644 --- a/ldblib.c +++ b/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.17 2000/06/12 13:52:05 roberto Exp roberto $ +** $Id: ldblib.c,v 1.18 2000/08/09 19:16:57 roberto Exp roberto $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -17,102 +17,96 @@ -static void settabss (lua_State *L, lua_Object t, const char *i, const char *v) { - lua_pushobject(L, t); +static void settabss (lua_State *L, const char *i, const char *v) { + lua_pushobject(L, -1); lua_pushstring(L, i); lua_pushstring(L, v); lua_settable(L); } -static void settabsi (lua_State *L, lua_Object t, const char *i, int v) { - lua_pushobject(L, t); +static void settabsi (lua_State *L, const char *i, int v) { + lua_pushobject(L, -1); lua_pushstring(L, i); lua_pushnumber(L, v); lua_settable(L); } -static void settabso (lua_State *L, lua_Object t, const char *i, lua_Object v) { - lua_pushobject(L, t); - lua_pushstring(L, i); - lua_pushobject(L, v); - lua_settable(L); -} - - -static void getinfo (lua_State *L) { +static int getinfo (lua_State *L) { lua_Debug ar; - lua_Object res; - lua_Object func = lua_getparam(L, 1); const char *options = luaL_opt_string(L, 2, "flnSu"); char buff[20]; - if (lua_isnumber(L, func)) { - if (!lua_getstack(L, (int)lua_getnumber(L, func), &ar)) { + if (lua_isnumber(L, 1)) { + if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) { lua_pushnil(L); /* level out of range */ - return; + return 1; } } - else if (lua_isfunction(L, func)) { - ar.func = func; + else if (lua_isfunction(L, 1)) { + lua_pushobject(L, 1); sprintf(buff, ">%.10s", options); options = buff; } else luaL_argerror(L, 1, "function or level expected"); - res = lua_createtable(L); if (!lua_getinfo(L, options, &ar)) luaL_argerror(L, 2, "invalid option"); + lua_newtable(L); for (; *options; options++) { switch (*options) { case 'S': - settabss(L, res, "source", ar.source); - settabsi(L, res, "linedefined", ar.linedefined); - settabss(L, res, "what", ar.what); + settabss(L, "source", ar.source); + settabsi(L, "linedefined", ar.linedefined); + settabss(L, "what", ar.what); break; case 'l': - settabsi(L, res, "currentline", ar.currentline); + settabsi(L, "currentline", ar.currentline); break; case 'u': - settabsi(L, res, "nups", ar.nups); + settabsi(L, "nups", ar.nups); break; case 'n': - settabss(L, res, "name", ar.name); - settabss(L, res, "namewhat", ar.namewhat); + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); break; case 'f': - settabso(L, res, "func", ar.func); + lua_pushobject(L, -1); + lua_pushstring(L, "func"); + lua_pushobject(L, -4); + lua_settable(L); break; } } - lua_pushobject(L, res); + return 1; /* return table */ } -static void getlocal (lua_State *L) { +static int getlocal (lua_State *L) { lua_Debug ar; - lua_Localvar lvar; + const char *name; if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ luaL_argerror(L, 1, "level out of range"); - lvar.index = luaL_check_int(L, 2); - if (lua_getlocal(L, &ar, &lvar)) { - lua_pushstring(L, lvar.name); - lua_pushobject(L, lvar.value); + name = lua_getlocal(L, &ar, luaL_check_int(L, 2)); + if (name) { + lua_pushstring(L, name); + lua_pushobject(L, -2); + return 2; + } + else { + lua_pushnil(L); + return 1; } - else lua_pushnil(L); } -static void setlocal (lua_State *L) { +static int setlocal (lua_State *L) { lua_Debug ar; - lua_Localvar lvar; if (!lua_getstack(L, luaL_check_int(L, 1), &ar)) /* level out of range? */ luaL_argerror(L, 1, "level out of range"); - lvar.index = luaL_check_int(L, 2); - lvar.value = luaL_nonnullarg(L, 3); - if (lua_setlocal(L, &ar, &lvar)) - lua_pushstring(L, lvar.name); - else lua_pushnil(L); + luaL_checktype(L, 3, "any"); + lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2))); + return 1; } @@ -128,47 +122,47 @@ static int callhook = LUA_NOREF; /* Lua reference to call hook function */ static void linef (lua_State *L, lua_Debug *ar) { if (linehook != LUA_NOREF) { + lua_getref(L, linehook); lua_pushnumber(L, ar->currentline); - lua_callfunction(L, lua_getref(L, linehook)); + lua_call(L, 1, 0); } } static void callf (lua_State *L, lua_Debug *ar) { if (callhook != LUA_NOREF) { + lua_getref(L, callhook); lua_pushstring(L, ar->event); - lua_callfunction(L, lua_getref(L, callhook)); + lua_call(L, 1, 0); } } -static void setcallhook (lua_State *L) { - lua_Object f = lua_getparam(L, 1); +static int setcallhook (lua_State *L) { lua_unref(L, callhook); - if (f == LUA_NOOBJECT) { + if (lua_isnull(L, 1)) { callhook = LUA_NOREF; lua_setcallhook(L, NULL); } else { - lua_pushobject(L, f); callhook = lua_ref(L, 1); lua_setcallhook(L, callf); } + return 0; } -static void setlinehook (lua_State *L) { - lua_Object f = lua_getparam(L, 1); +static int setlinehook (lua_State *L) { lua_unref(L, linehook); - if (f == LUA_NOOBJECT) { + if (lua_isnull(L, 1)) { linehook = LUA_NOREF; lua_setlinehook(L, NULL); } else { - lua_pushobject(L, f); linehook = lua_ref(L, 1); lua_setlinehook(L, linef); } + return 0; } diff --git a/ldebug.c b/ldebug.c index 2e851c1b..56bf6ddb 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.35 2000/08/14 17:59:20 roberto Exp roberto $ +** $Id: ldebug.c,v 1.36 2000/08/15 18:28:48 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -144,26 +144,28 @@ static Proto *getluaproto (StkId f) { } -int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { +const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum) { + const char *name; StkId f = ar->_func; Proto *fp = getluaproto(f); - if (!fp) return 0; /* `f' is not a Lua function? */ - v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f)); - if (!v->name) return 0; - v->value = luaA_putluaObject(L, (f+1)+(v->index-1)); - return 1; + if (!fp) return NULL; /* `f' is not a Lua function? */ + name = luaF_getlocalname(fp, localnum, lua_currentpc(f)); + if (!name) return NULL; + luaA_pushobject(L, (f+1)+(localnum-1)); /* push value */ + return name; } -int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { +const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum) { + const char *name; StkId f = ar->_func; Proto *fp = getluaproto(f); UNUSED(L); - if (!fp) return 0; /* `f' is not a Lua function? */ - v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f)); - if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */ - *((f+1)+(v->index-1)) = *v->value; - return 1; + if (!fp) return NULL; /* `f' is not a Lua function? */ + name = luaF_getlocalname(fp, localnum, lua_currentpc(f)); + if (!name || name[0] == '*') return NULL; /* `*' starts private locals */ + *((f+1)+(localnum-1)) = *(--L->top); + return name; } @@ -236,7 +238,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { func = ar->_func; else { what++; /* skip the '>' */ - func = ar->func; + func = L->top - 1; } for (; *what; what++) { switch (*what) { @@ -260,13 +262,13 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { } case 'f': { setnormalized(L->top, func); - incr_top; - ar->func = lua_pop(L); + incr_top; /* push function */ break; } default: return 0; /* invalid option */ } } + if (!isactive) L->top--; /* pop function */ return 1; } @@ -420,7 +422,7 @@ static const char *getfuncname (lua_State *L, StkId f, const char **name) { void luaG_typeerror (lua_State *L, StkId o, const char *op) { const char *name; const char *kind = getobjname(L, o, &name); - const char *t = lua_type(L, o); + const char *t = luaO_typename(o); if (kind) luaL_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)", op, kind, name, t); @@ -437,8 +439,8 @@ void luaG_binerror (lua_State *L, StkId p1, lua_Type t, const char *op) { void luaG_ordererror (lua_State *L, StkId top) { - const char *t1 = lua_type(L, top-2); - const char *t2 = lua_type(L, top-1); + const char *t1 = luaO_typename(top-2); + const char *t2 = luaO_typename(top-1); if (t1[2] == t2[2]) luaL_verror(L, "attempt to compare two %.10s values", t1); else diff --git a/ldo.c b/ldo.c index 06eb0d2d..074638c3 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.84 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: ldo.c,v 1.85 2000/08/10 19:50:47 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -41,8 +41,7 @@ void luaD_init (lua_State *L, int stacksize) { L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject); L->stack_last = L->stack+(stacksize-1); L->stacksize = stacksize; - L->Cstack.base = L->Cstack.lua2C = L->top = L->stack; - L->Cstack.num = 0; + L->Cbase = L->top = L->stack; } @@ -68,8 +67,8 @@ void luaD_checkstack (lua_State *L, int n) { static void restore_stack_limit (lua_State *L) { - if (L->top-L->stack < L->stacksize-1) - L->stack_last = L->stack+(L->stacksize-1); + if (L->top - L->stack < L->stacksize - 1) + L->stack_last = L->stack + (L->stacksize-1); } @@ -103,9 +102,8 @@ void luaD_openstack (lua_State *L, StkId pos) { void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) { if (L->allowhooks) { lua_Debug ar; - struct C_Lua_Stack oldCLS = L->Cstack; - StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; - L->Cstack.num = 0; + StkId old_Cbase = L->Cbase; + StkId old_top = L->Cbase = L->top; ar._func = func; ar.event = "line"; ar.currentline = line; @@ -113,7 +111,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) { (*linehook)(L, &ar); L->allowhooks = 1; L->top = old_top; - L->Cstack = oldCLS; + L->Cbase = old_Cbase; } } @@ -122,42 +120,36 @@ static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook, const char *event) { if (L->allowhooks) { lua_Debug ar; - struct C_Lua_Stack oldCLS = L->Cstack; - StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; - L->Cstack.num = 0; + StkId old_Cbase = L->Cbase; + StkId old_top = L->Cbase = L->top; ar._func = func; ar.event = event; L->allowhooks = 0; /* cannot call hooks inside a hook */ callhook(L, &ar); L->allowhooks = 1; L->top = old_top; - L->Cstack = oldCLS; + L->Cbase = old_Cbase; } } static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) { int nup = cl->nupvalues; /* number of upvalues */ - int numarg = L->top-base; - struct C_Lua_Stack oldCLS = L->Cstack; - StkId firstResult; + StkId old_Cbase = L->Cbase; + int nres; /* number of results */ if (nup > 0) { - int n = numarg; + int n = L->top - base; /* number of arguments */ luaD_checkstack(L, nup); /* open space for upvalues as extra arguments */ while (n--) *(base+nup+n) = *(base+n); L->top += nup; - numarg += nup; /* copy upvalues into stack */ while (nup--) *(base+nup) = cl->upvalue[nup]; } - L->Cstack.num = numarg; - L->Cstack.lua2C = base; - L->Cstack.base = L->top; - (*cl->f.c)(L); /* do the actual call */ - firstResult = L->Cstack.base; - L->Cstack = oldCLS; - return firstResult; + L->Cbase = base; /* new base for C function */ + nres = (*cl->f.c)(L); /* do the actual call */ + L->Cbase = old_Cbase; /* restore old C base */ + return L->top - nres; /* return index of first result */ } @@ -257,42 +249,36 @@ void lua_error (lua_State *L, const char *s) { static void chain_longjmp (lua_State *L, struct lua_longjmp *lj) { - lj->base = L->Cstack.base; - lj->numCblocks = L->numCblocks; + lj->status = 0; + lj->base = L->Cbase; lj->previous = L->errorJmp; L->errorJmp = lj; } -static void restore_longjmp (lua_State *L, struct lua_longjmp *lj) { - L->Cstack.num = 0; /* no results */ - L->top = L->Cstack.base = L->Cstack.lua2C = lj->base; - L->numCblocks = lj->numCblocks; +static int restore_longjmp (lua_State *L, struct lua_longjmp *lj) { + L->Cbase = lj->base; L->errorJmp = lj->previous; + return lj->status; } /* -** Execute a protected call. Assumes that function is at Cstack.base and -** parameters are on top of it. +** Execute a protected call. */ -int luaD_protectedrun (lua_State *L) { +int lua_call (lua_State *L, int nargs, int nresults) { + StkId func = L->top - (nargs+1); /* function to be called */ struct lua_longjmp myErrorJmp; chain_longjmp(L, &myErrorJmp); + if (nresults == LUA_MULTRET) nresults = MULT_RET; /* internal code */ if (setjmp(myErrorJmp.b) == 0) { - StkId base = L->Cstack.base; - luaD_call(L, base, MULT_RET); - L->Cstack.lua2C = base; /* position of the new results */ - L->Cstack.num = L->top - base; - L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */ - L->errorJmp = myErrorJmp.previous; - return 0; + luaD_call(L, func, nresults); } - else { /* an error occurred: restore the stack */ - restore_longjmp(L, &myErrorJmp); + else { /* an error occurred: restore the state */ + L->top = func; /* remove garbage from the stack */ restore_stack_limit(L); - return myErrorJmp.status; } + return restore_longjmp(L, &myErrorJmp); } @@ -302,20 +288,17 @@ int luaD_protectedrun (lua_State *L) { static int protectedparser (lua_State *L, ZIO *z, int bin) { struct lua_longjmp myErrorJmp; chain_longjmp(L, &myErrorJmp); - L->top = L->Cstack.base; /* clear C2Lua */ if (setjmp(myErrorJmp.b) == 0) { Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); - L->errorJmp = myErrorJmp.previous; - if (tf == NULL) return -1; /* `natural' end */ + if (tf == NULL) + myErrorJmp.status = -1; /* `natural' end */ luaV_Lclosure(L, tf, 0); - return 0; } - else { /* an error occurred */ - restore_longjmp(L, &myErrorJmp); + else { /* an error occurred: correct error code */ if (myErrorJmp.status == LUA_ERRRUN) myErrorJmp.status = LUA_ERRSYNTAX; - return myErrorJmp.status; /* error code */ } + return restore_longjmp(L, &myErrorJmp); /* error code */ } @@ -331,7 +314,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) { else { unsigned long newelems2 = 2*(L->nblocks-old_blocks); L->GCthreshold += newelems2; - status = luaD_protectedrun(L); + status = lua_call(L, 0, LUA_MULTRET); L->GCthreshold -= newelems2; } } while (bin && status == 0); diff --git a/ldo.h b/ldo.h index 0e91c7c8..ba168ccb 100644 --- a/ldo.h +++ b/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 1.21 2000/06/28 20:21:06 roberto Exp roberto $ +** $Id: ldo.h,v 1.22 2000/08/07 18:39:16 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -26,7 +26,6 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook); void luaD_call (lua_State *L, StkId func, int nResults); void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); void luaD_breakrun (lua_State *L, int errcode); -int luaD_protectedrun (lua_State *L); void luaD_checkstack (lua_State *L, int n); diff --git a/lgc.c b/lgc.c index 1e26ed51..f6768dd2 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.62 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lgc.c,v 1.63 2000/08/22 17:44:17 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -11,7 +11,6 @@ #include "lgc.h" #include "lmem.h" #include "lobject.h" -#include "lref.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" @@ -145,6 +144,43 @@ static void markall (lua_State *L) { } +static int hasmark (const TObject *o) { + /* valid only for locked objects */ + switch (o->ttype) { + case TAG_STRING: case TAG_USERDATA: + return tsvalue(o)->marked; + case TAG_TABLE: + return ismarked(hvalue(o)); + case TAG_LCLOSURE: case TAG_CCLOSURE: + return ismarked(clvalue(o)->mark); + default: /* number */ + return 1; + } +} + + +/* macro for internal debugging; check if a link of free refs is valid */ +#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n)) + +static void invalidaterefs (lua_State *L) { + int n = L->refSize; + int i; + for (i=0; irefArray[i]; + if (r->st == HOLD && !hasmark(&r->o)) + r->st = COLLECTED; + LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) || + (r->st == HOLD && hasmark(&r->o)) || + r->st == COLLECTED || + r->st == NONEXT || + (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)), + "inconsistent ref table"); + } + LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table"); +} + + + static void collectproto (lua_State *L) { Proto **p = &L->rootproto; Proto *next; @@ -300,7 +336,7 @@ void luaC_collect (lua_State *L, int all) { long lua_collectgarbage (lua_State *L, long limit) { unsigned long recovered = L->nblocks; /* to subtract `nblocks' after gc */ markall(L); - luaR_invalidaterefs(L); + invalidaterefs(L); luaC_collect(L, 0); recovered = recovered - L->nblocks; L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; diff --git a/liolib.c b/liolib.c index dc432b40..b73bd359 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 1.70 2000/08/14 19:10:14 roberto Exp roberto $ +** $Id: liolib.c,v 1.71 2000/08/22 17:47:17 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -61,13 +61,16 @@ typedef struct IOCtrl { static const char *const filenames[] = {"_INPUT", "_OUTPUT"}; -static void pushresult (lua_State *L, int i) { - if (i) +static int pushresult (lua_State *L, int i) { + if (i) { lua_pushuserdata(L, NULL); + return 1; + } else { lua_pushnil(L); lua_pushstring(L, strerror(errno)); lua_pushnumber(L, errno); + return 3;; } } @@ -79,8 +82,8 @@ static void pushresult (lua_State *L, int i) { */ -static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) { - void *p = lua_getuserdata(L, f); +static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) { + void *p = lua_touserdata(L, f); if (p != NULL) { /* is `f' a userdata ? */ int ftag = lua_tag(L, f); if (ftag == ctrl->iotag) /* does it have the correct tag? */ @@ -94,7 +97,7 @@ static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) { static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) { - FILE *f = gethandle(L, ctrl, lua_getparam(L, arg)); + FILE *f = gethandle(L, ctrl, arg); luaL_arg_check(L, f, arg, "invalid file handle"); return f; } @@ -102,9 +105,11 @@ static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) { static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) { FILE *f; - lua_pushglobals(L); - lua_pushref(L, ctrl->ref[inout]); - f = gethandle(L, ctrl, lua_rawget(L)); + lua_getglobals(L); + lua_getref(L, ctrl->ref[inout]); + lua_rawget(L); + f = gethandle(L, ctrl, -1); + lua_settop(L, -1); /* remove global */ if (f == NULL) luaL_verror(L, "global variable `%.10s' is not a file handle", filenames[inout]); @@ -122,12 +127,13 @@ static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f, #define setfile(L,ctrl,f,inout) (setfilebyname(L,ctrl,f,filenames[inout])) -static void setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) { +static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) { if (f == NULL) - pushresult(L, 0); + return pushresult(L, 0); else { setfile(L, ctrl, f, inout); lua_pushusertag(L, f, ctrl->iotag); + return 1; } } @@ -143,15 +149,15 @@ static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) { } -static void io_close (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); - pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2))); +static int io_close (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); + return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2))); } -static void file_collect (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); - if (ctrl == (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 2))) { +static int file_collect (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); + if (ctrl == (IOCtrl *)lua_touserdata(L, 2)) { /* collectig `ctrl' itself */ lua_unref(L, ctrl->ref[INFILE]); lua_unref(L, ctrl->ref[OUTFILE]); @@ -162,50 +168,54 @@ static void file_collect (lua_State *L) { if (f != stdin && f != stdout && f != stderr) CLOSEFILE(L, f); } + return 0; } -static void io_open (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); +static int io_open (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); FILE *f = fopen(luaL_check_string(L, 2), luaL_check_string(L, 3)); - if (f) lua_pushusertag(L, f, ctrl->iotag); - else pushresult(L, 0); + if (f) { + lua_pushusertag(L, f, ctrl->iotag); + return 1; + } + else + return pushresult(L, 0); } -static void io_fromto (lua_State *L, int inout, const char *mode) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); - lua_Object f = lua_getparam(L, 2); +static int io_fromto (lua_State *L, int inout, const char *mode) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); FILE *current; - if (f == LUA_NOOBJECT) { + if (lua_isnull(L, 2)) { closefile(L, ctrl, getfilebyref(L, ctrl, inout)); current = (inout == 0) ? stdin : stdout; } - else if (lua_tag(L, f) == ctrl->iotag) /* deprecated option */ - current = (FILE *)lua_getuserdata(L, f); + else if (lua_tag(L, 2) == ctrl->iotag) /* deprecated option */ + current = (FILE *)lua_touserdata(L, 2); else { const char *s = luaL_check_string(L, 2); current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode); } - setreturn(L, ctrl, current, inout); + return setreturn(L, ctrl, current, inout); } -static void io_readfrom (lua_State *L) { - io_fromto(L, INFILE, "r"); +static int io_readfrom (lua_State *L) { + return io_fromto(L, INFILE, "r"); } -static void io_writeto (lua_State *L) { - io_fromto(L, OUTFILE, "w"); +static int io_writeto (lua_State *L) { + return io_fromto(L, OUTFILE, "w"); } -static void io_appendto (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); +static int io_appendto (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); FILE *current = fopen(luaL_check_string(L, 2), "a"); - setreturn(L, ctrl, current, OUTFILE); + return setreturn(L, ctrl, current, OUTFILE); } @@ -342,28 +352,29 @@ static int read_chars (lua_State *L, FILE *f, size_t n) { } -static void io_read (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); - int arg = 2; - lua_Object op; - FILE *f = gethandle(L, ctrl, lua_getparam(L, arg)); - if (f) arg++; +static int io_read (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); + int lastarg = lua_gettop(L); + int firstarg = 2; + FILE *f = gethandle(L, ctrl, firstarg); + int n = 0; + if (f) firstarg++; else f = getfilebyref(L, ctrl, INFILE); /* get _INPUT */ - op = lua_getparam(L, arg); do { /* repeat for each part */ size_t l; int success; luaL_resetbuffer(L); - if (lua_isnumber(L, op)) - success = read_chars(L, f, (size_t)lua_getnumber(L, op)); + if (lua_isnumber(L, firstarg+n)) + success = read_chars(L, f, (size_t)lua_tonumber(L, firstarg+n)); else { - const char *p = luaL_opt_string(L, arg, "*l"); + const char *p = luaL_opt_string(L, firstarg+n, "*l"); if (p[0] != '*') success = read_pattern(L, f, p); /* deprecated! */ else { switch (p[1]) { case 'n': /* number */ - if (!read_number(L, f)) return; /* read fails */ + if (!read_number(L, f)) return n; /* read fails */ + n++; continue; /* number is already pushed; avoid the "pushstring" */ case 'l': /* line */ success = read_line(L, f); @@ -377,66 +388,69 @@ static void io_read (lua_State *L) { success = 0; /* must read something to succeed */ break; default: - luaL_argerror(L, arg, "invalid format"); + luaL_argerror(L, firstarg+n, "invalid format"); success = 0; /* to avoid warnings */ } } } l = luaL_getsize(L); - if (!success && l==0) return; /* read fails */ + if (!success && l==0) return n; /* read fails */ lua_pushlstring(L, luaL_buffer(L), l); - } while ((op = lua_getparam(L, ++arg)) != LUA_NOOBJECT); + n++; + } while (firstarg+n <= lastarg); + return n; } /* }====================================================== */ -static void io_write (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); +static int io_write (lua_State *L) { + int lastarg = lua_gettop(L); + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); int arg = 2; int status = 1; - lua_Object o; - FILE *f = gethandle(L, ctrl, lua_getparam(L, arg)); + FILE *f = gethandle(L, ctrl, arg); if (f) arg++; else f = getfilebyref(L, ctrl, OUTFILE); /* get _OUTPUT */ - while ((o = lua_getparam(L, arg)) != LUA_NOOBJECT) { - if (lua_type(L, o)[2] == 'm') { /* nuMber? */ /* LUA_NUMBER */ + for (; arg <= lastarg; arg++) { + if (lua_type(L, arg)[2] == 'm') { /* nuMber? */ /* LUA_NUMBER */ /* optimization: could be done exactly as for strings */ - status = status && fprintf(f, "%.16g", lua_getnumber(L, o)) > 0; + status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0; } else { size_t l; const char *s = luaL_check_lstr(L, arg, &l); status = status && (fwrite(s, sizeof(char), l, f) == l); } - arg++; } pushresult(L, status); + return 1; } -static void io_seek (lua_State *L) { +static int io_seek (lua_State *L) { static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; static const char *const modenames[] = {"set", "cur", "end", NULL}; - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); FILE *f = getnonullfile(L, ctrl, 2); int op = luaL_findstring(luaL_opt_string(L, 3, "cur"), modenames); long offset = luaL_opt_long(L, 4, 0); luaL_arg_check(L, op != -1, 3, "invalid mode"); op = fseek(f, offset, mode[op]); if (op) - pushresult(L, 0); /* error */ - else + return pushresult(L, 0); /* error */ + else { lua_pushnumber(L, ftell(f)); + return 1; + } } -static void io_flush (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1)); - lua_Object of = lua_getparam(L, 2); - FILE *f = gethandle(L, ctrl, of); - luaL_arg_check(L, f || of == LUA_NOOBJECT, 2, "invalid file handle"); - pushresult(L, fflush(f) == 0); +static int io_flush (lua_State *L) { + IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1); + FILE *f = gethandle(L, ctrl, 2); + luaL_arg_check(L, f || lua_isnull(L, 2), 2, "invalid file handle"); + return pushresult(L, fflush(f) == 0); } /* }====================================================== */ @@ -448,39 +462,43 @@ static void io_flush (lua_State *L) { ** ======================================================= */ -static void io_execute (lua_State *L) { +static int io_execute (lua_State *L) { lua_pushnumber(L, system(luaL_check_string(L, 1))); + return 1; } -static void io_remove (lua_State *L) { - pushresult(L, remove(luaL_check_string(L, 1)) == 0); +static int io_remove (lua_State *L) { + return pushresult(L, remove(luaL_check_string(L, 1)) == 0); } -static void io_rename (lua_State *L) { - pushresult(L, rename(luaL_check_string(L, 1), +static int io_rename (lua_State *L) { + return pushresult(L, rename(luaL_check_string(L, 1), luaL_check_string(L, 2)) == 0); } -static void io_tmpname (lua_State *L) { +static int io_tmpname (lua_State *L) { lua_pushstring(L, tmpnam(NULL)); + return 1; } -static void io_getenv (lua_State *L) { +static int io_getenv (lua_State *L) { lua_pushstring(L, getenv(luaL_check_string(L, 1))); /* if NULL push nil */ + return 1; } -static void io_clock (lua_State *L) { +static int io_clock (lua_State *L) { lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC); + return 1; } -static void io_date (lua_State *L) { +static int io_date (lua_State *L) { char b[256]; const char *s = luaL_opt_string(L, 1, "%c"); struct tm *stm; @@ -490,10 +508,11 @@ static void io_date (lua_State *L) { lua_pushstring(L, b); else lua_error(L, "invalid `date' format"); + return 1; } -static void setloc (lua_State *L) { +static int setloc (lua_State *L) { static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME}; static const char *const catnames[] = {"all", "collate", "ctype", "monetary", @@ -501,25 +520,28 @@ static void setloc (lua_State *L) { int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames); luaL_arg_check(L, op != -1, 2, "invalid option"); lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1))); + return 1; } -static void io_exit (lua_State *L) { +static int io_exit (lua_State *L) { exit(luaL_opt_int(L, 1, EXIT_SUCCESS)); + return 0; /* to avoid warnings */ } /* }====================================================== */ -static void io_debug (lua_State *L) { +static int io_debug (lua_State *L) { for (;;) { char buffer[250]; fprintf(stderr, "lua_debug> "); if (fgets(buffer, sizeof(buffer), stdin) == 0 || strcmp(buffer, "cont\n") == 0) - return; + return 0; lua_dostring(L, buffer); + lua_settop(L, 0); /* remove eventual returns */ } } @@ -529,12 +551,11 @@ static void io_debug (lua_State *L) { #define MAXMESSAGE (MESSAGESIZE*10) -static void errorfb (lua_State *L) { +static int errorfb (lua_State *L) { char buff[MAXMESSAGE]; int level = 1; /* skip level 0 (it's this function) */ lua_Debug ar; - lua_Object alertfunc; - sprintf(buff, "error: %.200s\n", lua_getstring(L, lua_getparam(L, 1))); + sprintf(buff, "error: %.200s\n", lua_tostring(L, 1)); while (lua_getstack(L, level++, &ar)) { char buffchunk[60]; lua_getinfo(L, "Snl", &ar); @@ -572,13 +593,14 @@ static void errorfb (lua_State *L) { sprintf(buff+strlen(buff), " [%.70s]", buffchunk); strcat(buff, "\n"); } - lua_pushglobals(L); + lua_getglobals(L); lua_pushstring(L, LUA_ALERT); - alertfunc = lua_rawget(L); - if (lua_isfunction(L, alertfunc)) { /* avoid loop if _ALERT is not defined */ + lua_rawget(L); + if (lua_isfunction(L, -1)) { /* avoid loop if _ALERT is not defined */ lua_pushstring(L, buff); - lua_callfunction(L, alertfunc); + lua_call(L, 1, 0); } + return 0; } diff --git a/llimits.h b/llimits.h index f7412acf..c716b0dd 100644 --- a/llimits.h +++ b/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.11 2000/06/28 17:03:32 roberto Exp roberto $ +** $Id: llimits.h,v 1.12 2000/08/15 18:28:48 roberto Exp roberto $ ** Limits, basic types, and some other "installation-dependent" definitions ** See Copyright Notice in lua.h */ @@ -197,12 +197,6 @@ typedef unsigned long Instruction; #define RFIELDS_PER_FLUSH (LFIELDS_PER_FLUSH/2) -/* maximum number of values printed in one call to `print' */ -#ifndef MAXPRINT -#define MAXPRINT 40 /* arbitrary limit */ -#endif - - /* maximum lookback to find a real constant (for code generation) */ #ifndef LOOKBACKNUMS #define LOOKBACKNUMS 20 /* arbitrary constant */ diff --git a/lmathlib.c b/lmathlib.c index 86850cc9..d6957e76 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.25 2000/06/12 13:52:05 roberto Exp roberto $ +** $Id: lmathlib.c,v 1.26 2000/08/09 19:16:57 roberto Exp roberto $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -33,138 +33,169 @@ #endif -static void math_abs (lua_State *L) { +static int math_abs (lua_State *L) { lua_pushnumber(L, fabs(luaL_check_number(L, 1))); + return 1; } -static void math_sin (lua_State *L) { +static int math_sin (lua_State *L) { lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1)))); + return 1; } -static void math_cos (lua_State *L) { +static int math_cos (lua_State *L) { lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1)))); + return 1; } -static void math_tan (lua_State *L) { +static int math_tan (lua_State *L) { lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1)))); + return 1; } -static void math_asin (lua_State *L) { +static int math_asin (lua_State *L) { lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1)))); + return 1; } -static void math_acos (lua_State *L) { +static int math_acos (lua_State *L) { lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1)))); + return 1; } -static void math_atan (lua_State *L) { +static int math_atan (lua_State *L) { lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1)))); + return 1; } -static void math_atan2 (lua_State *L) { +static int math_atan2 (lua_State *L) { lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2)))); + return 1; } -static void math_ceil (lua_State *L) { +static int math_ceil (lua_State *L) { lua_pushnumber(L, ceil(luaL_check_number(L, 1))); + return 1; } -static void math_floor (lua_State *L) { +static int math_floor (lua_State *L) { lua_pushnumber(L, floor(luaL_check_number(L, 1))); + return 1; } -static void math_mod (lua_State *L) { +static int math_mod (lua_State *L) { lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2))); + return 1; } -static void math_sqrt (lua_State *L) { +static int math_sqrt (lua_State *L) { lua_pushnumber(L, sqrt(luaL_check_number(L, 1))); + return 1; } -static void math_pow (lua_State *L) { +static int math_pow (lua_State *L) { lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2))); + return 1; } -static void math_log (lua_State *L) { +static int math_log (lua_State *L) { lua_pushnumber(L, log(luaL_check_number(L, 1))); + return 1; } -static void math_log10 (lua_State *L) { +static int math_log10 (lua_State *L) { lua_pushnumber(L, log10(luaL_check_number(L, 1))); + return 1; } -static void math_exp (lua_State *L) { +static int math_exp (lua_State *L) { lua_pushnumber(L, exp(luaL_check_number(L, 1))); + return 1; } -static void math_deg (lua_State *L) { +static int math_deg (lua_State *L) { lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE); + return 1; } -static void math_rad (lua_State *L) { +static int math_rad (lua_State *L) { lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE); + return 1; } -static void math_frexp (lua_State *L) { +static int math_frexp (lua_State *L) { int e; lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e)); lua_pushnumber(L, e); + return 2; } -static void math_ldexp (lua_State *L) { +static int math_ldexp (lua_State *L) { lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2))); + return 1; } -static void math_min (lua_State *L) { - int i = 1; - double dmin = luaL_check_number(L, i); - while (lua_getparam(L, ++i) != LUA_NOOBJECT) { +static int math_min (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + double dmin = luaL_check_number(L, 1); + int i; + for (i=2; i<=n; i++) { double d = luaL_check_number(L, i); if (d < dmin) dmin = d; } lua_pushnumber(L, dmin); + return 1; } -static void math_max (lua_State *L) { - int i = 1; - double dmax = luaL_check_number(L, i); - while (lua_getparam(L, ++i) != LUA_NOOBJECT) { +static int math_max (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + double dmax = luaL_check_number(L, 1); + int i; + for (i=2; i<=n; i++) { double d = luaL_check_number(L, i); if (d > dmax) dmax = d; } lua_pushnumber(L, dmax); + return 1; } -static void math_random (lua_State *L) { +static int math_random (lua_State *L) { /* the '%' avoids the (rare) case of r==1, and is needed also because on some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */ double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX; - if (lua_getparam(L, 1) == LUA_NOOBJECT) /* no arguments? */ - lua_pushnumber(L, r); /* Number between 0 and 1 */ - else { - int l, u; /* lower & upper limits */ - if (lua_getparam(L, 2) == LUA_NOOBJECT) { /* only one argument? */ - l = 1; - u = luaL_check_int(L, 1); + switch (lua_gettop(L)) { /* check number of arguments */ + case 0: { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; } - else { /* two arguments */ - l = luaL_check_int(L, 1); - u = luaL_check_int(L, 2); + case 1: { /* only upper limit */ + int u = luaL_check_int(L, 1); + luaL_arg_check(L, 1<=u, 1, "interval is empty"); + lua_pushnumber(L, (int)(r*u)+1); /* integer between 1 and `u' */ + break; } - luaL_arg_check(L, l<=u, 1, "interval is empty"); - lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */ + case 2: { /* lower and upper limits */ + int l = luaL_check_int(L, 1); + int u = luaL_check_int(L, 2); + luaL_arg_check(L, l<=u, 2, "interval is empty"); + lua_pushnumber(L, (int)(r*(u-l+1))+l); /* integer between `l' and `u' */ + break; + } + default: lua_error(L, "wrong number of arguments"); } + return 1; } -static void math_randomseed (lua_State *L) { +static int math_randomseed (lua_State *L) { srand(luaL_check_int(L, 1)); + return 0; } @@ -199,9 +230,10 @@ static const struct luaL_reg mathlib[] = { */ void lua_mathlibopen (lua_State *L) { luaL_openl(L, mathlib); - lua_pushcfunction(L, math_pow); lua_pushnumber(L, 0); /* to get its tag */ - lua_settagmethod(L, lua_tag(L, lua_pop(L)), "pow"); + lua_pushcfunction(L, math_pow); + lua_settagmethod(L, lua_tag(L, -2), "pow"); + lua_settop(L, -1); /* remove number */ lua_pushnumber(L, PI); lua_setglobal(L, "PI"); } diff --git a/lref.c b/lref.c deleted file mode 100644 index c3fc57af..00000000 --- a/lref.c +++ /dev/null @@ -1,118 +0,0 @@ -/* -** $Id: lref.c,v 1.17 2000/08/09 19:16:57 roberto Exp roberto $ -** reference mechanism -** See Copyright Notice in lua.h -*/ - - -#include "lua.h" - -#include "lapi.h" -#include "ldo.h" -#include "lmem.h" -#include "lref.h" -#include "lstate.h" - - -int lua_ref (lua_State *L, int lock) { - int ref; - luaA_checkCargs(L, 1); - if (ttype(L->top-1) == TAG_NIL) - ref = LUA_REFNIL; - else { - if (L->refFree != NONEXT) { /* is there a free place? */ - ref = L->refFree; - L->refFree = L->refArray[ref].st; - } - else { /* no more free places */ - luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref, - "reference table overflow", MAX_INT); - ref = L->refSize++; - } - L->refArray[ref].o = *(L->top-1); - L->refArray[ref].st = lock ? LOCK : HOLD; - } - L->top--; - return ref; -} - - -void lua_unref (lua_State *L, int ref) { - if (ref >= 0) { - if (ref >= L->refSize || L->refArray[ref].st >= 0) - lua_error(L, "Lua API error - " - "invalid argument for function `lua_unref'"); - L->refArray[ref].st = L->refFree; - L->refFree = ref; - } -} - - -int lua_pushref (lua_State *L, int ref) { - if (ref == LUA_REFNIL) - ttype(L->top) = TAG_NIL; - else if (0 <= ref && ref < L->refSize && - (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD)) - *L->top = L->refArray[ref].o; - else - return 0; - incr_top; - return 1; -} - - -void lua_beginblock (lua_State *L) { - luaM_growvector(L, L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack, - "too many nested blocks", L->stacksize); - L->Cblocks[L->numCblocks] = L->Cstack; - L->numCblocks++; -} - - -void lua_endblock (lua_State *L) { - if (L->numCblocks <= 0) - lua_error(L, "Lua API error - no block to end"); - --L->numCblocks; - L->Cstack = L->Cblocks[L->numCblocks]; - L->top = L->Cstack.base; -} - - - - - - -static int hasmark (const TObject *o) { - /* valid only for locked objects */ - switch (o->ttype) { - case TAG_STRING: case TAG_USERDATA: - return tsvalue(o)->marked; - case TAG_TABLE: - return ismarked(hvalue(o)); - case TAG_LCLOSURE: case TAG_CCLOSURE: - return ismarked(clvalue(o)->mark); - default: /* number */ - return 1; - } -} - - -/* for internal debugging only; check if a link of free refs is valid */ -#define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n)) - -void luaR_invalidaterefs (lua_State *L) { - int n = L->refSize; - int i; - for (i=0; irefArray[i]; - if (r->st == HOLD && !hasmark(&r->o)) - r->st = COLLECTED; - LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) || - r->st == COLLECTED || - r->st == NONEXT || - (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)), - "inconsistent ref table"); - } - LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table"); -} - diff --git a/lref.h b/lref.h deleted file mode 100644 index 4aec948d..00000000 --- a/lref.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -** $Id: lref.h,v 1.5 1999/12/27 17:33:22 roberto Exp roberto $ -** reference mechanism -** See Copyright Notice in lua.h -*/ - -#ifndef lref_h -#define lref_h - -#include "lobject.h" - - -#define NONEXT -1 /* to end the free list */ -#define HOLD -2 -#define COLLECTED -3 -#define LOCK -4 - - -struct Ref { - TObject o; - int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */ -}; - - -void luaR_invalidaterefs (lua_State *L); - -#endif diff --git a/lstate.c b/lstate.c index a50252bc..d3d045f0 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.32 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lstate.c,v 1.33 2000/08/14 17:46:07 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -9,13 +9,11 @@ #include "lua.h" -#include "lauxlib.h" #include "lbuiltin.h" #include "ldo.h" #include "lgc.h" #include "llex.h" #include "lmem.h" -#include "lref.h" #include "lstate.h" #include "lstring.h" #include "ltable.h" @@ -35,8 +33,6 @@ lua_State *lua_newstate (int stacksize, int put_builtin) { L->Mbuffbase = 0; L->Mbuffsize = 0; L->Mbuffnext = 0; - L->Cblocks = NULL; - L->numCblocks = 0; L->rootproto = NULL; L->rootcl = NULL; L->roottable = NULL; @@ -84,8 +80,6 @@ void lua_close (lua_State *L) { luaM_free(L, L->IMtable); luaM_free(L, L->refArray); luaM_free(L, L->Mbuffer); - luaM_free(L, L->Cblocks); - LUA_ASSERT(L->numCblocks == 0, "Cblocks still open"); LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks"); luaM_free(L, L); LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!"); diff --git a/lstate.h b/lstate.h index d177c3a6..65e4c6ef 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.35 2000/08/07 18:39:16 roberto Exp roberto $ +** $Id: lstate.h,v 1.36 2000/08/08 20:42:07 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -18,6 +18,21 @@ typedef TObject *StkId; /* index to stack elements */ +/* +** marks for Reference array +*/ +#define NONEXT -1 /* to end the free list */ +#define HOLD -2 +#define COLLECTED -3 +#define LOCK -4 + + +struct Ref { + TObject o; + int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */ +}; + + /* ** chain list of long jumps */ @@ -26,20 +41,6 @@ struct lua_longjmp { struct lua_longjmp *previous; volatile int status; /* error code */ StkId base; - int numCblocks; -}; - - -/* -** stack layout for C point of view: -** [lua2C, lua2C+num) - `array' lua2C -** [lua2C+num, base) - space for extra lua_Objects (limbo) -** [base, L->top) - `stack' C2Lua -*/ -struct C_Lua_Stack { - StkId base; - StkId lua2C; - int num; }; @@ -57,14 +58,12 @@ struct lua_State { StkId stack; /* stack base */ StkId stack_last; /* last free slot in the stack */ int stacksize; - struct C_Lua_Stack Cstack; /* C2lua struct */ + StkId Cbase; /* base for current C function */ struct lua_longjmp *errorJmp; /* current error recover point */ char *Mbuffer; /* global buffer */ size_t Mbuffbase; /* current first position of Mbuffer */ size_t Mbuffsize; /* size of Mbuffer */ size_t Mbuffnext; /* next position to fill in Mbuffer */ - struct C_Lua_Stack *Cblocks; - int numCblocks; /* number of nested Cblocks */ /* global state */ Proto *rootproto; /* list of all prototypes */ Closure *rootcl; /* list of all closures */ diff --git a/lstrlib.c b/lstrlib.c index 16066499..c380359b 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.45 2000/06/12 14:37:18 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -25,10 +25,11 @@ static void addnchar (lua_State *L, const char *s, size_t n) { } -static void str_len (lua_State *L) { +static int str_len (lua_State *L) { size_t l; luaL_check_lstr(L, 1, &l); lua_pushnumber(L, l); + return 1; } @@ -43,7 +44,7 @@ static long posrelat (long pos, size_t len) { } -static void str_sub (lua_State *L) { +static int str_sub (lua_State *L) { size_t l; const char *s = luaL_check_lstr(L, 1, &l); long start = posrelat(luaL_check_long(L, 2), l); @@ -53,10 +54,11 @@ static void str_sub (lua_State *L) { if (start <= end) lua_pushlstring(L, s+start-1, end-start+1); else lua_pushstring(L, ""); + return 1; } -static void str_lower (lua_State *L) { +static int str_lower (lua_State *L) { size_t l; size_t i; const char *s = luaL_check_lstr(L, 1, &l); @@ -64,10 +66,11 @@ static void str_lower (lua_State *L) { for (i=0; i 0) addnchar(L, s, l); closeandpush(L); + return 1; } -static void str_byte (lua_State *L) { +static int str_byte (lua_State *L) { size_t l; const char *s = luaL_check_lstr(L, 1, &l); long pos = posrelat(luaL_opt_long(L, 2, 1), l); luaL_arg_check(L, 0level; i++) { - int l = cap->capture[i].len; - if (l == -1) lua_error(L, "unfinished capture"); - lua_pushlstring(L, cap->capture[i].init, l); - } -} - - static int check_capture (lua_State *L, int l, struct Capture *cap) { l -= '1'; if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) @@ -400,20 +398,31 @@ static const char *lmemfind (const char *s1, size_t l1, } -static void str_find (lua_State *L) { +static int push_captures (lua_State *L, struct Capture *cap) { + int i; + for (i=0; ilevel; i++) { + int l = cap->capture[i].len; + if (l == -1) lua_error(L, "unfinished capture"); + lua_pushlstring(L, cap->capture[i].init, l); + } + return cap->level; /* number of strings pushed */ +} + + +static int str_find (lua_State *L) { size_t l1, l2; const char *s = luaL_check_lstr(L, 1, &l1); const char *p = luaL_check_lstr(L, 2, &l2); long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1; struct Capture cap; luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range"); - if (lua_getparam(L, 4) != LUA_NOOBJECT || - strpbrk(p, SPECIALS) == NULL) { /* no special characters? */ + if (lua_gettop(L) > 3 || /* extra argument? */ + strpbrk(p, SPECIALS) == NULL) { /* or no special characters? */ const char *s2 = lmemfind(s+init, l1-init, p, l2); if (s2) { lua_pushnumber(L, s2-s+1); lua_pushnumber(L, s2-s+l2); - return; + return 2; } } else { @@ -426,19 +435,19 @@ static void str_find (lua_State *L) { if ((res=match(L, s1, p, &cap)) != NULL) { lua_pushnumber(L, s1-s+1); /* start */ lua_pushnumber(L, res-s); /* end */ - push_captures(L, &cap); - return; + return push_captures(L, &cap) + 2; } } while (s1++= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)), + 3, "string or function expected"); luaL_resetbuffer(L); cap.src_end = src+srcl; while (n < max_s) { @@ -496,7 +504,7 @@ static void str_gsub (lua_State *L) { e = match(L, src, p, &cap); if (e) { n++; - add_s(L, newp, &cap); + add_s(L, &cap); } if (e && e>src) /* non empty match? */ src = e; /* skip it */ @@ -508,6 +516,7 @@ static void str_gsub (lua_State *L) { addnchar(L, src, cap.src_end-src); closeandpush(L); lua_pushnumber(L, n); /* number of substitutions */ + return 2; } /* }====================================================== */ @@ -534,7 +543,7 @@ static void luaI_addquoted (lua_State *L, int arg) { /* maximum size of each format specification (such as '%-099.99d') */ #define MAX_FORMAT 20 /* arbitrary limit */ -static void str_format (lua_State *L) { +static int str_format (lua_State *L) { int arg = 1; const char *strfrmt = luaL_check_string(L, arg); luaL_resetbuffer(L); @@ -597,6 +606,7 @@ static void str_format (lua_State *L) { } } closeandpush(L); /* push the result */ + return 1; } diff --git a/ltests.c b/ltests.c index b0f38e7c..0d83f011 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.33 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: ltests.c,v 1.34 2000/08/15 20:14:27 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -10,7 +10,6 @@ #include #include -#define LUA_SINGLESTATE #include "lua.h" @@ -38,11 +37,11 @@ void luaB_opentests (lua_State *L); -static void setnameval (lua_Object t, const char *name, int val) { - lua_pushobject(t); - lua_pushstring(name); - lua_pushnumber(val); - lua_settable(); +static void setnameval (lua_State *L, const char *name, int val) { + lua_pushobject(L, -1); + lua_pushstring(L, name); + lua_pushnumber(L, val); + lua_settable(L); } @@ -65,7 +64,7 @@ static const char *const instrname[NUM_OPCODES] = { }; -static int pushop (Proto *p, int pc) { +static int pushop (lua_State *L, Proto *p, int pc) { char buff[100]; Instruction i = p->code[pc]; OpCode o = GET_OPCODE(i); @@ -85,146 +84,161 @@ static int pushop (Proto *p, int pc) { sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i)); break; } - lua_pushstring(buff); + lua_pushstring(L, buff); return (o != OP_END); } -static void listcode (void) { - lua_Object o = luaL_nonnullarg(1); - lua_Object t = lua_createtable(); +static int listcode (lua_State *L) { int pc; Proto *p; int res; - luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected"); - p = clvalue(o)->f.l; - setnameval(t, "maxstack", p->maxstacksize); - setnameval(t, "numparams", p->numparams); + luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected"); + p = clvalue(luaA_index(L, 1))->f.l; + lua_newtable(L); + setnameval(L, "maxstack", p->maxstacksize); + setnameval(L, "numparams", p->numparams); pc = 0; do { - lua_pushobject(t); - lua_pushnumber(pc+1); - res = pushop(p, pc++); - lua_settable(); + lua_pushobject(L, -1); + lua_pushnumber(L, pc+1); + res = pushop(L, p, pc++); + lua_settable(L); } while (res); - lua_pushobject(t); + return 1; } -static void liststrings (void) { - lua_Object o = luaL_nonnullarg(1); - lua_Object t = lua_createtable(); +static int liststrings (lua_State *L) { Proto *p; int i; - luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected"); - p = clvalue(o)->f.l; + luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected"); + p = clvalue(luaA_index(L, 1))->f.l; + lua_newtable(L); for (i=0; inkstr; i++) { - lua_pushobject(t); - lua_pushnumber(i+1); - lua_pushstring(p->kstr[i]->str); - lua_settable(); + lua_pushobject(L, -1); + lua_pushnumber(L, i+1); + lua_pushstring(L, p->kstr[i]->str); + lua_settable(L); } - lua_pushobject(t); + return 1; } -static void listlocals (void) { - lua_Object o = luaL_nonnullarg(1); +static int listlocals (lua_State *L) { Proto *p; - int pc = luaL_check_int(2) - 1; - int i = 1; + int pc = luaL_check_int(L, 2) - 1; + int i = 0; const char *name; - luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected"); - p = clvalue(o)->f.l; - while ((name = luaF_getlocalname(p, i++, pc)) != NULL) - lua_pushstring(name); + luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected"); + p = clvalue(luaA_index(L, 1))->f.l; + while ((name = luaF_getlocalname(p, ++i, pc)) != NULL) + lua_pushstring(L, name); + return i-1; } /* }====================================================== */ -static void get_limits (void) { - lua_Object t = lua_createtable(); - setnameval(t, "BITS_INT", BITS_INT); - setnameval(t, "LFPF", LFIELDS_PER_FLUSH); - setnameval(t, "MAXARG_A", MAXARG_A); - setnameval(t, "MAXARG_B", MAXARG_B); - setnameval(t, "MAXARG_S", MAXARG_S); - setnameval(t, "MAXARG_U", MAXARG_U); - setnameval(t, "MAXLOCALS", MAXLOCALS); - setnameval(t, "MAXPARAMS", MAXPARAMS); - setnameval(t, "MAXSTACK", MAXSTACK); - setnameval(t, "MAXUPVALUES", MAXUPVALUES); - setnameval(t, "MAXVARSLH", MAXVARSLH); - setnameval(t, "RFPF", RFIELDS_PER_FLUSH); - setnameval(t, "SIZE_A", SIZE_A); - setnameval(t, "SIZE_B", SIZE_B); - setnameval(t, "SIZE_OP", SIZE_OP); - setnameval(t, "SIZE_U", SIZE_U); - lua_pushobject(t); +static int get_limits (lua_State *L) { + lua_newtable(L); + setnameval(L, "BITS_INT", BITS_INT); + setnameval(L, "LFPF", LFIELDS_PER_FLUSH); + setnameval(L, "MAXARG_A", MAXARG_A); + setnameval(L, "MAXARG_B", MAXARG_B); + setnameval(L, "MAXARG_S", MAXARG_S); + setnameval(L, "MAXARG_U", MAXARG_U); + setnameval(L, "MAXLOCALS", MAXLOCALS); + setnameval(L, "MAXPARAMS", MAXPARAMS); + setnameval(L, "MAXSTACK", MAXSTACK); + setnameval(L, "MAXUPVALUES", MAXUPVALUES); + setnameval(L, "MAXVARSLH", MAXVARSLH); + setnameval(L, "RFPF", RFIELDS_PER_FLUSH); + setnameval(L, "SIZE_A", SIZE_A); + setnameval(L, "SIZE_B", SIZE_B); + setnameval(L, "SIZE_OP", SIZE_OP); + setnameval(L, "SIZE_U", SIZE_U); + return 1; } -static void mem_query (void) { - lua_Object arg = lua_getparam(1); - if (arg == LUA_NOOBJECT) { - lua_pushnumber(memdebug_total); - lua_pushnumber(memdebug_numblocks); - lua_pushnumber(memdebug_maxmem); - } - else - memdebug_memlimit = luaL_check_int(1); -} - - -static void hash_query (void) { - lua_Object o = luaL_nonnullarg(1); - if (lua_getparam(2) == LUA_NOOBJECT) { - luaL_arg_check(ttype(o) == TAG_STRING, 1, "string expected"); - lua_pushnumber(tsvalue(o)->u.s.hash); +static int mem_query (lua_State *L) { + if (lua_isnull(L, 1)) { + lua_pushnumber(L, memdebug_total); + lua_pushnumber(L, memdebug_numblocks); + lua_pushnumber(L, memdebug_maxmem); + return 3; } else { - const Hash *t = hvalue(luaL_tablearg(2)); - lua_pushnumber(luaH_mainposition(t, o) - t->node); + memdebug_memlimit = luaL_check_int(L, 1); + return 0; } } -static void table_query (void) { - const Hash *t = hvalue(luaL_tablearg(1)); - int i = luaL_opt_int(2, -1); +static int hash_query (lua_State *L) { + if (lua_isnull(L, 2)) { + luaL_arg_check(L, lua_tag(L, 1) == TAG_STRING, 1, "string expected"); + lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash); + } + else { + Hash *t; + luaL_checktype(L, 2, "table"); + t = hvalue(luaA_index(L, 2)); + lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node); + } + return 1; +} + + +static int table_query (lua_State *L) { + const Hash *t; + int i = luaL_opt_int(L, 2, -1); + luaL_checktype(L, 1, "table"); + t = hvalue(luaA_index(L, 1)); if (i == -1) { - lua_pushnumber(t->size); - lua_pushnumber(t->firstfree - t->node); + lua_pushnumber(L, t->size); + lua_pushnumber(L, t->firstfree - t->node); + return 2; } else if (i < t->size) { - luaA_pushobject(lua_state, &t->node[i].key); - luaA_pushobject(lua_state, &t->node[i].val); - if (t->node[i].next) - lua_pushnumber(t->node[i].next - t->node); + luaA_pushobject(L, &t->node[i].key); + luaA_pushobject(L, &t->node[i].val); + if (t->node[i].next) { + lua_pushnumber(L, t->node[i].next - t->node); + return 3; + } + else + return 2; } + return 0; } -static void string_query (void) { - lua_State *L = lua_state; - stringtable *tb = (*luaL_check_string(1) == 's') ? &L->strt : &L->udt; - int s = luaL_opt_int(2, 0) - 1; +static int string_query (lua_State *L) { + stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt; + int s = luaL_opt_int(L, 2, 0) - 1; if (s==-1) { - lua_pushnumber(tb->nuse); - lua_pushnumber(tb->size); + lua_pushnumber(L ,tb->nuse); + lua_pushnumber(L ,tb->size); + return 2; } else if (s < tb->size) { TString *ts; + int n = 0; for (ts = tb->hash[s]; ts; ts = ts->nexthash) { ttype(L->top) = TAG_STRING; tsvalue(L->top) = ts; incr_top; + n++; } + return n; } + return 0; } + /* ** {====================================================== ** function to test the API with C. It interprets a kind of "assembler" @@ -238,21 +252,33 @@ static void skip (const char **pc) { while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++; } -static int getnum (const char **pc) { +static int getnum (const char **pc, int *reg) { int res = 0; + int sig = 1; + int ref = 0; skip(pc); + if (**pc == 'r') { + ref = 1; + (*pc)++; + } + else if (**pc == '-') { + sig = -1; + (*pc)++; + } while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0'; - return res; + if (!ref) + return sig*res; + else + return reg[res]; } static int getreg (const char **pc) { skip(pc); - if (*(*pc)++ != 'r') lua_error("`testC' expecting a register"); - return getnum(pc); + (*pc)++; /* skip the `r' */ + return getnum(pc, NULL); } -static const char *getname (const char **pc) { - static char buff[30]; +static const char *getname (char *buff, const char **pc) { int i = 0; skip(pc); while (**pc != '\0' && !strchr(delimits, **pc)) @@ -264,159 +290,148 @@ static const char *getname (const char **pc) { #define EQ(s1) (strcmp(s1, inst) == 0) +#define getnum ((getnum)(&pc, reg)) +#define getreg ((getreg)(&pc)) +#define getname ((getname)(buff, &pc)) -static void testC (void) { - lua_Object reg[10]; - const char *pc = luaL_check_string(1); + +static int testC (lua_State *L) { + char buff[30]; + int reg[10]; + const char *pc = luaL_check_string(L, 1); for (;;) { - const char *inst = getname(&pc); - if EQ("") return; - else if EQ("pushnum") { - lua_pushnumber(getnum(&pc)); + const char *inst = getname; + if EQ("") return 0; + else if EQ("return") { + return getnum; } - else if EQ("createtable") { - reg[getreg(&pc)] = lua_createtable(); + else if EQ("retall") { + return lua_gettop(L) - 1; + } + else if EQ("gettop") { + reg[getreg] = lua_gettop(L); + } + else if EQ("settop") { + lua_settop(L, getnum); + } + else if EQ("setreg") { + int n = getreg; + reg[n] = lua_tonumber(L, getnum); + } + else if EQ("pushnum") { + lua_pushnumber(L, getnum); + } + else if EQ("newtable") { + lua_newtable(L); } else if EQ("closure") { - lua_CFunction f = lua_getcfunction(lua_getglobal(getname(&pc))); - lua_pushcclosure(f, getnum(&pc)); + lua_CFunction f; + lua_getglobal(L, getname); + f = lua_tocfunction(L, -1); + lua_settop(L, -1); + lua_pushcclosure(L, f, getnum); } - else if EQ("pop") { - reg[getreg(&pc)] = lua_pop(); + else if EQ("pushobject") { + lua_pushobject(L, getnum); } else if EQ("getglobal") { - int n = getreg(&pc); - reg[n] = lua_getglobal(getname(&pc)); + lua_getglobal(L, getname); } else if EQ("ref") { - lua_pushnumber(lua_ref(0)); - reg[getreg(&pc)] = lua_pop(); + reg[getreg] = lua_ref(L, 0); } else if EQ("reflock") { - lua_pushnumber(lua_ref(1)); - reg[getreg(&pc)] = lua_pop(); + reg[getreg] = lua_ref(L, 1); } else if EQ("getref") { - int n = getreg(&pc); - reg[n] = lua_getref((int)lua_getnumber(reg[getreg(&pc)])); + int n = getreg; + reg[n] = lua_getref(L, getnum); } else if EQ("unref") { - lua_unref((int)lua_getnumber(reg[getreg(&pc)])); - } - else if EQ("getparam") { - int n = getreg(&pc); - reg[n] = lua_getparam(getnum(&pc)+1); /* skips the command itself */ - } - else if EQ("getresult") { - int n = getreg(&pc); - reg[n] = lua_getparam(getnum(&pc)); + lua_unref(L, getnum); } else if EQ("setglobal") { - lua_setglobal(getname(&pc)); - } - else if EQ("pushglobals") { - lua_pushglobals(); + lua_setglobal(L, getname); } else if EQ("pushstring") { - lua_pushstring(getname(&pc)); - } - else if EQ("pushreg") { - lua_pushobject(reg[getreg(&pc)]); + lua_pushstring(L, getname); } else if EQ("call") { - if (lua_call(getname(&pc))) lua_error(NULL); + int narg = getnum; + int nres = getnum; + if (lua_call(L, narg, nres)) lua_error(L, NULL); } else if EQ("gettable") { - reg[getreg(&pc)] = lua_gettable(); + lua_gettable(L); } else if EQ("rawget") { - reg[getreg(&pc)] = lua_rawget(); + lua_rawget(L); } else if EQ("settable") { - lua_settable(); + lua_settable(L); } else if EQ("rawset") { - lua_rawset(); + lua_rawset(L); } else if EQ("tag") { - lua_pushnumber(lua_tag(reg[getreg(&pc)])); + int n = getreg; + reg[n] = lua_tag(L, getnum); } else if EQ("type") { - lua_pushstring(lua_type(reg[getreg(&pc)])); - } - else if EQ("next") { - int n = getreg(&pc); - n = lua_next(reg[n], (int)lua_getnumber(reg[getreg(&pc)])); - lua_pushnumber(n); + lua_pushstring(L, lua_type(L, getnum)); } else if EQ("equal") { - int n1 = getreg(&pc); - int n2 = getreg(&pc); - lua_pushnumber(lua_equal(reg[n1], reg[n2])); + int n1 = getreg; + int n2 = getnum; + int n3 = getnum; + reg[n1] = lua_equal(L, n2, n3); } else if EQ("pushusertag") { - int val = getreg(&pc); - int tag = getreg(&pc); - lua_pushusertag((void *)(int)lua_getnumber(reg[val]), - (int)lua_getnumber(reg[tag])); + int val = getnum; + int tag = getnum; + lua_pushusertag(L, (void *)val, tag); } else if EQ("udataval") { - int n = getreg(&pc); - lua_pushnumber((int)lua_getuserdata(reg[getreg(&pc)])); - reg[n] = lua_pop(); + int n = getreg; + reg[n] = (int)lua_touserdata(L, getnum); } else if EQ("settagmethod") { - int n = getreg(&pc); - lua_settagmethod((int)lua_getnumber(reg[n]), getname(&pc)); - } - else if EQ("beginblock") { - lua_beginblock(); - } - else if EQ("endblock") { - lua_endblock(); + int n = getnum; + lua_settagmethod(L, n, getname); } else if EQ("newstate") { - int stacksize = getnum(&pc); - lua_State *L1 = lua_newstate(stacksize, getnum(&pc)); + int stacksize = getnum; + lua_State *L1 = lua_newstate(stacksize, getnum); if (L1) - lua_pushuserdata(L1); + lua_pushuserdata(L, L1); else - lua_pushnil(); + lua_pushnil(L); } else if EQ("closestate") { - (lua_close)((lua_State *)lua_getuserdata(reg[getreg(&pc)])); + (lua_close)((lua_State *)lua_touserdata(L, getnum)); } else if EQ("doremote") { - lua_Object ol1 = reg[getreg(&pc)]; - lua_Object str = reg[getreg(&pc)]; + int ol1 = getnum; + int str = getnum; lua_State *L1; - lua_Object temp; int status; - if (!lua_isuserdata(ol1) || !lua_isstring(str)) - lua_error("bad arguments for `doremote'"); - L1 = (lua_State *)lua_getuserdata(ol1); - status = (lua_dostring)(L1, lua_getstring(str)); + if (!lua_isuserdata(L, ol1) || !lua_isstring(L, str)) + lua_error(L, "bad arguments for `doremote'"); + L1 = (lua_State *)lua_touserdata(L, ol1); + status = lua_dostring(L1, lua_tostring(L, str)); if (status != 0) { - lua_pushnil(); - lua_pushnumber(status); + lua_pushnil(L); + lua_pushnumber(L, status); } else { - int i = 1; - while ((temp = (lua_getresult)(L1, i++)) != LUA_NOOBJECT) - lua_pushstring((lua_getstring)(L1, temp)); + int i = 0; + while (!lua_isnull(L, ++i)) + lua_pushstring(L, lua_tostring(L1, i)); } } -#if LUA_DEPRECATETFUNCS - else if EQ("rawsetglobal") { - lua_rawsetglobal(getname(&pc)); - } - else if EQ("rawgetglobal") { - int n = getreg(&pc); - reg[n] = lua_rawgetglobal(getname(&pc)); - } -#endif - else luaL_verror(lua_state, "unknown command in `testC': %.20s", inst); + else luaL_verror(L, "unknown instruction %.30s", buff); } + return 0; } /* }====================================================== */ @@ -424,22 +439,20 @@ static void testC (void) { static const struct luaL_reg tests_funcs[] = { - {"hash", (lua_CFunction)hash_query}, - {"limits", (lua_CFunction)get_limits}, - {"listcode", (lua_CFunction)listcode}, - {"liststrings", (lua_CFunction)liststrings}, - {"listlocals", (lua_CFunction)listlocals}, - {"querystr", (lua_CFunction)string_query}, - {"querytab", (lua_CFunction)table_query}, - {"testC", (lua_CFunction)testC}, - {"totalmem", (lua_CFunction)mem_query} + {"hash", hash_query}, + {"limits", get_limits}, + {"listcode", listcode}, + {"liststrings", liststrings}, + {"listlocals", listlocals}, + {"querystr", string_query}, + {"querytab", table_query}, + {"testC", testC}, + {"totalmem", mem_query} }; void luaB_opentests (lua_State *L) { - if (lua_state != NULL) return; /* do not open tests for auxiliar states */ - lua_state = L; - luaL_openl(tests_funcs); + luaL_openl(L, tests_funcs); } #endif diff --git a/lua.c b/lua.c index b3b8e6ea..3a50ceb2 100644 --- a/lua.c +++ b/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.44 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lua.c,v 1.45 2000/08/14 17:45:59 roberto Exp roberto $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -10,14 +10,14 @@ #include #include -#define LUA_SINGLESTATE - #include "lua.h" #include "luadebug.h" #include "lualib.h" + lua_State *lua_state = NULL; +#define L lua_state #ifndef PROMPT @@ -54,10 +54,10 @@ extern void USERINIT (void); #else #define USERINIT userinit static void userinit (void) { - lua_iolibopen(); - lua_strlibopen(); - lua_mathlibopen(); - lua_dblibopen(); + lua_iolibopen(L); + lua_strlibopen(L); + lua_mathlibopen(L); + lua_dblibopen(L); } #endif @@ -68,10 +68,10 @@ static handler lreset (void) { static void lstop (void) { - lua_setlinehook(lua_state, old_linehook); - lua_setcallhook(lua_state, old_callhook); + lua_setlinehook(L, old_linehook); + lua_setcallhook(L, old_callhook); lreset(); - lua_error("interrupted!"); + lua_error(L, "interrupted!"); } @@ -79,15 +79,15 @@ static void laction (int i) { (void)i; /* to avoid warnings */ signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop, terminate process (default action) */ - old_linehook = lua_setlinehook(lua_state, (lua_Hook)lstop); - old_callhook = lua_setcallhook(lua_state, (lua_Hook)lstop); + old_linehook = lua_setlinehook(L, (lua_Hook)lstop); + old_callhook = lua_setcallhook(L, (lua_Hook)lstop); } -static int ldo (int (*f)(lua_State *L, const char *), const char *name) { +static int ldo (int (*f)(lua_State *l, const char *), const char *name) { int res; handler h = lreset(); - res = f(lua_state, name); /* dostring | dofile */ + res = f(L, name); /* dostring | dofile */ signal(SIGINT, h); /* restore old action */ if (res == LUA_ERRMEM) { /* Lua gives no message in such case, so lua.c provides one */ @@ -122,29 +122,29 @@ static void print_version (void) { static void assign (char *arg) { char *eq = strchr(arg, '='); *eq = '\0'; /* spilt `arg' in two strings (name & value) */ - lua_pushstring(eq+1); - lua_setglobal(arg); + lua_pushstring(L, eq+1); + lua_setglobal(L, arg); } -static lua_Object getargs (char *argv[]) { - lua_Object args = lua_createtable(); +static void getargs (char *argv[]) { int i; + lua_newtable(L); for (i=0; argv[i]; i++) { /* arg[i] = argv[i] */ - lua_pushobject(args); lua_pushnumber(i); - lua_pushstring(argv[i]); lua_settable(); + lua_pushobject(L, -1); lua_pushnumber(L, i); + lua_pushstring(L, argv[i]); lua_settable(L); } /* arg.n = maximum index in table `arg' */ - lua_pushobject(args); lua_pushstring("n"); - lua_pushnumber(i-1); lua_settable(); - return args; + lua_pushobject(L, -1); lua_pushstring(L, "n"); + lua_pushnumber(L, i-1); lua_settable(L); } -static void l_getargs (void) { - char **argv = (char **)lua_getuserdata(lua_getparam(1)); - lua_pushobject(getargs(argv)); +static int l_getargs (lua_State *l) { + char **argv = (char **)lua_touserdata(l, 1); + getargs(argv); + return 1; } @@ -173,9 +173,11 @@ static void manual_input (int version, int prompt) { while (cont) { char buffer[MAXINPUT]; int i = 0; - lua_beginblock(); if (prompt) { - const char *s = lua_getstring(lua_getglobal("_PROMPT")); + const char *s; + lua_getglobal(L, "_PROMPT"); + s = lua_tostring(L, -1); + lua_settop(L, -1); /* remove global */ if (!s) s = PROMPT; fputs(s, stdout); } @@ -198,7 +200,7 @@ static void manual_input (int version, int prompt) { } buffer[i] = '\0'; ldo(lua_dostring, buffer); - lua_endblock(); + lua_settop(L, 0); /* remove eventual results */ } printf("\n"); } @@ -262,8 +264,8 @@ static int handle_argv (char *argv[], struct Options *opt) { print_message(); return EXIT_FAILURE; } - lua_pushobject(getargs(argv+i)); /* collect remaining arguments */ - lua_setglobal("arg"); + getargs(argv+i); /* collect remaining arguments */ + lua_setglobal(L, "arg"); return file_input(argv[i]); /* stop scanning arguments */ } case 's': { @@ -296,9 +298,9 @@ static void getstacksize (int argc, char *argv[], struct Options *opt) { static void register_getargs (char *argv[]) { - lua_pushuserdata(argv); - lua_pushcclosure(l_getargs, 1); - lua_setglobal("getargs"); + lua_pushuserdata(L, argv); + lua_pushcclosure(L, l_getargs, 1); + lua_setglobal(L, "getargs"); } @@ -307,12 +309,12 @@ int main (int argc, char *argv[]) { int status; opt.toclose = 0; getstacksize(argc, argv, &opt); /* handle option `-s' */ - lua_state = lua_newstate(opt.stacksize, 1); /* create state */ + L = lua_newstate(opt.stacksize, 1); /* create state */ USERINIT(); /* open libraries */ register_getargs(argv); /* create `getargs' function */ status = handle_argv(argv+1, &opt); if (opt.toclose) - lua_close(); + lua_close(L); return status; } diff --git a/lua.h b/lua.h index 96f3597a..43459a4d 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.58 2000/08/14 19:10:14 roberto Exp roberto $ +** $Id: lua.h,v 1.59 2000/08/17 13:18:01 roberto Exp roberto $ ** Lua - An Extensible Extension Language ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil ** e-mail: lua@tecgraf.puc-rio.br @@ -30,8 +30,10 @@ #define LUA_ANYTAG (-1) +#define LUA_MULTRET (-1) -/* error code for lua_do* */ + +/* error codes for lua_do* */ #define LUA_ERRFILE 2 #define LUA_ERRSYNTAX 3 #define LUA_ERRRUN 1 @@ -40,95 +42,103 @@ typedef struct lua_State lua_State; -typedef void (*lua_CFunction) (lua_State *L); - -typedef struct lua_TObject *lua_Object; - -#define LUA_NOOBJECT ((lua_Object)0) +typedef int (*lua_CFunction) (lua_State *L); +/* +** state manipulation +*/ lua_State *lua_newstate (int stacksize, int builtin); void lua_close (lua_State *L); -lua_Object lua_settagmethod (lua_State *L, int tag, const char *event); - /* In: new method */ -lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event); -int lua_newtag (lua_State *L); -int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); -void lua_settag (lua_State *L, int tag); /* In: object */ - -void lua_error (lua_State *L, const char *s); -int lua_dofile (lua_State *L, const char *filename); - /* Out: returns */ -int lua_dostring (lua_State *L, const char *str); - /* Out: returns */ -int lua_dobuffer (lua_State *L, const char *buff, size_t size, - const char *name); /* Out: returns */ -int lua_callfunction (lua_State *L, lua_Object f); - /* In: arguments; Out: returns */ - -void lua_beginblock (lua_State *L); -void lua_endblock (lua_State *L); - -void lua_pushglobals (lua_State *L); -void lua_setglobals (lua_State *L, lua_Object newtable); - -lua_Object lua_lua2C (lua_State *L, int number); -#define lua_getparam lua_lua2C -#define lua_getresult lua_lua2C - -const char *lua_type (lua_State *L, lua_Object obj); - -int lua_isnil (lua_State *L, lua_Object obj); -int lua_istable (lua_State *L, lua_Object obj); -int lua_isuserdata (lua_State *L, lua_Object obj); -int lua_iscfunction (lua_State *L, lua_Object obj); -int lua_isnumber (lua_State *L, lua_Object obj); -int lua_isstring (lua_State *L, lua_Object obj); -int lua_isfunction (lua_State *L, lua_Object obj); - -int lua_equal (lua_State *L, lua_Object o1, lua_Object o2); - -double lua_getnumber (lua_State *L, lua_Object obj); -const char *lua_getstring (lua_State *L, lua_Object obj); -size_t lua_strlen (lua_State *L, lua_Object obj); -lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj); -void *lua_getuserdata (lua_State *L, lua_Object obj); +/* +** basic stack manipulation +*/ +int lua_gettop (lua_State *L); +void lua_settop (lua_State *L, int index); +void lua_pushobject (lua_State *L, int index); -void lua_pushnil (lua_State *L); +/* +** access functions (stack -> C) +*/ + +const char *lua_type (lua_State *L, int index); +int lua_isnumber (lua_State *L, int index); +int lua_iscfunction (lua_State *L, int index); +int lua_tag (lua_State *L, int index); + +int lua_equal (lua_State *L, int index1, int index2); + +double lua_tonumber (lua_State *L, int index); +const char *lua_tostring (lua_State *L, int index); +size_t lua_strlen (lua_State *L, int index); +lua_CFunction lua_tocfunction (lua_State *L, int index); +void *lua_touserdata (lua_State *L, int index); + + +/* +** push functions (C -> stack) +*/ +void lua_pushnil (lua_State *L); void lua_pushnumber (lua_State *L, double n); void lua_pushlstring (lua_State *L, const char *s, size_t len); void lua_pushstring (lua_State *L, const char *s); void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); void lua_pushusertag (lua_State *L, void *u, int tag); -void lua_pushobject (lua_State *L, lua_Object obj); -lua_Object lua_pop (lua_State *L); -lua_Object lua_getglobal (lua_State *L, const char *name); -void lua_setglobal (lua_State *L, const char *name); /* In: value */ +/* +** get functions (Lua -> stack) +*/ +void lua_getglobal (lua_State *L, const char *name); +void lua_gettable (lua_State *L); +void lua_rawget (lua_State *L); +void lua_getglobals (lua_State *L); +void lua_gettagmethod (lua_State *L, int tag, const char *event); -void lua_settable (lua_State *L); /* In: table, index, value */ -lua_Object lua_gettable (lua_State *L); /* In: table, index */ +int lua_getref (lua_State *L, int ref); -void lua_rawset (lua_State *L); /* In: table, index, value */ -lua_Object lua_rawget (lua_State *L); /* In: table, index */ +void lua_newtable (lua_State *L); -int lua_tag (lua_State *L, lua_Object obj); -int lua_next (lua_State *L, lua_Object o, int i); - /* Out: index, value */ +/* +** set functions (stack -> Lua) +*/ +void lua_setglobal (lua_State *L, const char *name); +void lua_settable (lua_State *L); +void lua_rawset (lua_State *L); +void lua_setglobals (lua_State *L); +void lua_settagmethod (lua_State *L, int tag, const char *event); +int lua_ref (lua_State *L, int lock); + + +/* +** "do" functions (run Lua code) +*/ +int lua_call (lua_State *L, int nargs, int nresults); +int lua_dofile (lua_State *L, const char *filename); +int lua_dostring (lua_State *L, const char *str); +int lua_dobuffer (lua_State *L, const char *buff, size_t size, + const char *name); + + +/* +** miscelaneous functions +*/ +int lua_newtag (lua_State *L); +int lua_copytagmethods (lua_State *L, int tagto, int tagfrom); +void lua_settag (lua_State *L, int tag); + +void lua_error (lua_State *L, const char *s); -int lua_ref (lua_State *L, int lock); /* In: value */ -int lua_pushref (lua_State *L, int ref); /* Out: value */ void lua_unref (lua_State *L, int ref); -lua_Object lua_createtable (lua_State *L); - long lua_collectgarbage (lua_State *L, long limit); +int lua_next (lua_State *L, int index, int i); + /* @@ -137,122 +147,17 @@ long lua_collectgarbage (lua_State *L, long limit); ** =============================================================== */ -#ifndef LUA_SINGLESTATE - -#define lua_call(L,name) lua_callfunction(L, lua_getglobal(L, name)) -#define lua_getref(L, ref) (lua_pushref(L, ref) ? lua_pop(L) : LUA_NOOBJECT) -#define lua_refobject(L,o,l) (lua_pushobject(L, o), lua_ref(L, l)) #define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n)) #define lua_pushuserdata(L,u) lua_pushusertag(L, u, 0) #define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0) #define lua_clonetag(L,t) lua_copytagmethods(L, lua_newtag(L), (t)) -#else - -#define lua_call(name) lua_callfunction(lua_getglobal(name)) -#define lua_getref(ref) (lua_pushref(ref) ? lua_pop() : LUA_NOOBJECT) -#define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l)) -#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n)) -#define lua_pushuserdata(u) lua_pushusertag(u, 0) -#define lua_pushcfunction(f) lua_pushcclosure(f, 0) -#define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t)) - -#endif - - - -#ifdef LUA_SINGLESTATE -/* -** {============================================================== -** Macros for single-state use -** =============================================================== -*/ - -extern lua_State *lua_state; - -#define lua_open() ((void)(lua_state?0:(lua_state=lua_newstate(0, 1)))) - -#define lua_close() (lua_close)(lua_state) -#define lua_settagmethod(tag,event) (lua_settagmethod)(lua_state, tag,event) -#define lua_gettagmethod(tag,event) (lua_gettagmethod)(lua_state, tag,event) -#define lua_newtag() (lua_newtag)(lua_state) -#define lua_copytagmethods(tagto,tagfrom) \ - (lua_copytagmethods)(lua_state, tagto,tagfrom) -#define lua_settag(tag) (lua_settag)(lua_state, tag) -#define lua_error(s) (lua_error)(lua_state, s) -#define lua_dofile(filename) (lua_dofile)(lua_state, filename) -#define lua_dostring(str) (lua_dostring)(lua_state, str) -#define lua_dobuffer(b,s,n) (lua_dobuffer)(lua_state, b,s,n) -#define lua_callfunction(f) (lua_callfunction)(lua_state, f) -#define lua_beginblock() (lua_beginblock)(lua_state) -#define lua_endblock() (lua_endblock)(lua_state) -#define lua_pushglobals() (lua_pushglobals)(lua_state) -#define lua_setglobals(t) (lua_setglobals)(lua_state, t) -#define lua_lua2C(number) (lua_lua2C)(lua_state, number) -#define lua_type(obj) (lua_type)(lua_state, obj) -#define lua_isnil(obj) (lua_isnil)(lua_state, obj) -#define lua_istable(obj) (lua_istable)(lua_state, obj) -#define lua_isuserdata(obj) (lua_isuserdata)(lua_state, obj) -#define lua_iscfunction(obj) (lua_iscfunction)(lua_state, obj) -#define lua_isnumber(obj) (lua_isnumber)(lua_state, obj) -#define lua_isstring(obj) (lua_isstring)(lua_state, obj) -#define lua_isfunction(obj) (lua_isfunction)(lua_state, obj) -#define lua_equal(o1,o2) (lua_equal)(lua_state, o1,o2) -#define lua_getnumber(obj) (lua_getnumber)(lua_state, obj) -#define lua_getstring(obj) (lua_getstring)(lua_state, obj) -#define lua_strlen(obj) (lua_strlen)(lua_state, obj) -#define lua_getcfunction(obj) (lua_getcfunction)(lua_state, obj) -#define lua_getuserdata(obj) (lua_getuserdata)(lua_state, obj) -#define lua_pushnil() (lua_pushnil)(lua_state) -#define lua_pushnumber(n) (lua_pushnumber)(lua_state, n) -#define lua_pushlstring(s,len) (lua_pushlstring)(lua_state, s,len) -#define lua_pushstring(s) (lua_pushstring)(lua_state, s) -#define lua_pushusertag(u,tag) (lua_pushusertag)(lua_state, u,tag) -#define lua_pushobject(obj) (lua_pushobject)(lua_state, obj) -#define lua_pop() (lua_pop)(lua_state) -#define lua_getglobal(name) (lua_getglobal)(lua_state, name) -#define lua_setglobal(name) (lua_setglobal)(lua_state, name) -#define lua_settable() (lua_settable)(lua_state) -#define lua_gettable() (lua_gettable)(lua_state) -#define lua_rawset() (lua_rawset)(lua_state) -#define lua_rawget() (lua_rawget)(lua_state) -#define lua_tag(obj) (lua_tag)(lua_state, obj) -#define lua_next(o,i) (lua_next)(lua_state, o,i) -#define lua_ref(lock) (lua_ref)(lua_state, lock) -#define lua_pushref(ref) (lua_pushref)(lua_state, ref) -#define lua_unref(ref) (lua_unref)(lua_state, ref) -#define lua_createtable() (lua_createtable)(lua_state) -#define lua_collectgarbage(limit) (lua_collectgarbage)(lua_state, limit) -/* -** the following typecast is a little dirty, but we know of no other -** way to keep compatibility with old definition of `lua_CFunction' -*/ -#define lua_pushcclosure(fn,n) \ - (lua_pushcclosure)(lua_state, (lua_CFunction)(fn), n) - - -/* -** }============================================================== -*/ -#endif - -/* -** compatibility with 3.2 -** these functions are only available when Lua is compiled with -** the option LUA_DEPRECATETFUNCS -*/ - -#define lua_rawsettable lua_rawset -#define lua_rawgettable lua_rawget - -lua_Object lua_rawgetglobal (lua_State *L, const char *name); -void lua_rawsetglobal (lua_State *L, const char *name);/* In: value */ - -#ifdef LUA_SINGLESTATE -#define lua_rawgetglobal(name) (lua_rawgetglobal(lua_state, name)) -#define lua_rawsetglobal(name) (lua_rawsetglobal(lua_state, name)) -#endif - +#define lua_isfunction(L,n) (*lua_type(L,n) == 'f') +#define lua_isstring(L,n) (lua_tostring(L,n)) +#define lua_istable(L,n) (*lua_type(L,n) == 't') +#define lua_isuserdata(L,n) (*lua_type(L,n) == 'u') +#define lua_isnil(L,n) (lua_type(L,n)[2] == 'l') +#define lua_isnull(L,n) (*lua_type(L,n) == 'N') #endif diff --git a/luadebug.h b/luadebug.h index 6944cc17..67472ad9 100644 --- a/luadebug.h +++ b/luadebug.h @@ -1,5 +1,5 @@ /* -** $Id: luadebug.h,v 1.11 2000/08/08 20:42:07 roberto Exp roberto $ +** $Id: luadebug.h,v 1.12 2000/08/11 16:17:28 roberto Exp roberto $ ** Debugging API ** See Copyright Notice in lua.h */ @@ -19,8 +19,8 @@ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); int lua_getstack (lua_State *L, int level, lua_Debug *ar); int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar); -int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v); -int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v); +const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum); +const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum); lua_Hook lua_setcallhook (lua_State *L, lua_Hook func); lua_Hook lua_setlinehook (lua_State *L, lua_Hook func); @@ -36,16 +36,8 @@ struct lua_Debug { const char *name; /* (n) */ const char *namewhat; /* (n) `global', `tag method', `local', `field' */ int nups; /* (u) number of upvalues */ - lua_Object func; /* (f) function being executed */ /* private part */ - lua_Object _func; /* active function */ -}; - - -struct lua_Localvar { - int index; - const char *name; - lua_Object value; + struct lua_TObject *_func; /* active function */ }; diff --git a/lundump.c b/lundump.c index 386bebc9..2e3478ad 100644 --- a/lundump.c +++ b/lundump.c @@ -1,5 +1,5 @@ /* -** $Id: lundump.c,v 1.24 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lundump.c,v 1.25 2000/08/24 14:19:39 roberto Exp roberto $ ** load bytecodes from files ** See Copyright Notice in lua.h */ @@ -130,7 +130,7 @@ static void LoadCode (lua_State* L, Proto* tf, ZIO* Z) } static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z) -{ +{ } static Proto* LoadFunction (lua_State* L, ZIO* Z, int native);