support for `light' userdata + simpler support for `boxed' udata

This commit is contained in:
Roberto Ierusalimschy 2002-04-05 15:54:31 -03:00
parent f438d00ef3
commit 237969724f
12 changed files with 71 additions and 64 deletions

44
lapi.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 1.181 2002/03/27 12:49:53 roberto Exp roberto $
** $Id: lapi.c,v 1.182 2002/04/02 20:43:18 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@ -278,7 +278,12 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
LUA_API void *lua_touserdata (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, index);
return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL : uvalue(o)->uv.value;
if (o == NULL) return NULL;
switch (ttype(o)) {
case LUA_TUSERDATA: return (uvalue(o) + 1);
case LUA_TUDATAVAL: return pvalue(o);
default: return NULL;
}
}
@ -356,6 +361,14 @@ LUA_API void lua_pushboolean (lua_State *L, int b) {
}
LUA_API void lua_pushudataval (lua_State *L, void *p) {
lua_lock(L);
setpvalue(L->top, p);
api_incr_top(L);
lua_unlock(L);
}
/*
** get functions (Lua -> stack)
@ -472,7 +485,7 @@ LUA_API void lua_setmetatable (lua_State *L, int objindex) {
StkId obj, mt;
lua_lock(L);
api_checknelems(L, 1);
obj = luaA_indexAcceptable(L, objindex);
obj = luaA_index(L, objindex);
mt = --L->top;
if (ttype(mt) == LUA_TNIL)
mt = defaultmeta(L);
@ -649,31 +662,14 @@ LUA_API void lua_concat (lua_State *L, int n) {
}
static Udata *pushnewudata (lua_State *L, size_t size) {
Udata *u = luaS_newudata(L, size);
setuvalue(L->top, u);
api_incr_top(L);
return uvalue(L->top-1);
}
LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u;
void *p;
lua_lock(L);
u = pushnewudata(L, size);
p = u->uv.value;
lua_unlock(L);
return p;
}
LUA_API void lua_newuserdatabox (lua_State *L, void *p) {
Udata *u;
lua_lock(L);
u = pushnewudata(L, 0);
u->uv.value = p;
u = luaS_newudata(L, size);
setuvalue(L->top, u);
api_incr_top(L);
lua_unlock(L);
return u + 1;
}

View File

@ -1,5 +1,5 @@
/*
** $Id: lbaselib.c,v 1.62 2002/03/27 15:30:41 roberto Exp roberto $
** $Id: lbaselib.c,v 1.63 2002/04/02 20:42:20 roberto Exp roberto $
** Basic library
** See Copyright Notice in lua.h
*/
@ -206,7 +206,7 @@ static int passresults (lua_State *L, int status, int oldtop) {
if (nresults > 0)
return nresults; /* results are already on the stack */
else {
lua_newuserdatabox(L, NULL); /* at least one result to signal no errors */
lua_pushboolean(L, 1); /* at least one result to signal no errors */
return 1;
}
}
@ -383,6 +383,7 @@ static int luaB_tostring (lua_State *L) {
sprintf(buff, "function: %p", lua_topointer(L, 1));
break;
case LUA_TUSERDATA:
case LUA_TUDATAVAL:
sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
break;
case LUA_TNIL:
@ -439,7 +440,7 @@ static void base_open (lua_State *L) {
static int luaB_resume (lua_State *L) {
lua_State *co = (lua_State *)lua_touserdata(L, lua_upvalueindex(1));
lua_State *co = (lua_State *)lua_getfrombox(L, lua_upvalueindex(1));
if (lua_resume(L, co) != 0)
lua_error(L, "error running co-routine");
return lua_gettop(L);
@ -448,7 +449,7 @@ static int luaB_resume (lua_State *L) {
static int gc_coroutine (lua_State *L) {
lua_State *co = (lua_State *)lua_touserdata(L, 1);
lua_State *co = (lua_State *)lua_getfrombox(L, 1);
lua_closethread(L, co);
return 0;
}
@ -471,7 +472,7 @@ static int luaB_coroutine (lua_State *L) {
lua_unref(L, ref);
}
lua_cobegin(NL, n-1);
lua_newuserdatabox(L, NL);
lua_newpointerbox(L, NL);
lua_pushliteral(L, "Coroutine");
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);

5
lgc.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 1.132 2002/03/20 18:54:29 roberto Exp roberto $
** $Id: lgc.c,v 1.133 2002/03/26 18:55:50 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@ -46,7 +46,8 @@ typedef struct GCState {
#define ismarkable(o) (!((1 << ttype(o)) & \
((1 << LUA_TNIL) | (1 << LUA_TNUMBER) | (1 << LUA_TBOOLEAN))))
((1 << LUA_TNIL) | (1 << LUA_TNUMBER) | \
(1 << LUA_TBOOLEAN) | (1 << LUA_TUDATAVAL))))
static void reallymarkobject (GCState *st, TObject *o);

View File

@ -1,5 +1,5 @@
/*
** $Id: liolib.c,v 1.133 2002/03/27 15:30:41 roberto Exp roberto $
** $Id: liolib.c,v 2.1 2002/04/04 20:24:56 roberto Exp roberto $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
@ -54,11 +54,11 @@ static int pushresult (lua_State *L, int i) {
static FILE *tofile (lua_State *L, int findex) {
FILE *f = (FILE *)lua_touserdata(L, findex);
FILE **f = (FILE **)lua_touserdata(L, findex);
if (f && lua_getmetatable(L, findex) &&
lua_equal(L, -1, lua_upvalueindex(1))) {
lua_pop(L, 1);
return f;
return *f;
}
luaL_argerror(L, findex, "bad file");
return NULL; /* to avoid warnings */
@ -66,7 +66,7 @@ static FILE *tofile (lua_State *L, int findex) {
static void newfile (lua_State *L, FILE *f) {
lua_newuserdatabox(L, f);
lua_newpointerbox(L, f);
lua_pushliteral(L, FILEHANDLE);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);

View File

@ -1,5 +1,5 @@
/*
** $Id: lobject.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
** $Id: lobject.c,v 1.75 2002/02/07 17:25:12 roberto Exp roberto $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@ -59,7 +59,9 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
return 1;
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
default: /* all other types are equal if pointers are equal */
case LUA_TUDATAVAL:
return pvalue(t1) == pvalue(t2);
default: /* other types are equal if struct pointers are equal */
return tsvalue(t1) == tsvalue(t2);
}
}

View File

@ -1,5 +1,5 @@
/*
** $Id: lobject.h,v 1.127 2002/03/18 18:16:16 roberto Exp roberto $
** $Id: lobject.h,v 1.128 2002/03/25 17:47:14 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@ -13,15 +13,15 @@
/* tags for values visible from Lua */
#define NUM_TAGS 6
#define NUM_TAGS LUA_TFUNCTION
typedef union {
void *p;
union TString *ts;
union Udata *u;
union Closure *cl;
struct Table *h;
struct lua_TObject *v;
lua_Number n;
int b;
} Value;
@ -35,12 +35,12 @@ typedef struct lua_TObject {
/* Macros to access values */
#define ttype(o) ((o)->tt)
#define pvalue(o) ((o)->value.p)
#define nvalue(o) ((o)->value.n)
#define tsvalue(o) ((o)->value.ts)
#define uvalue(o) ((o)->value.u)
#define clvalue(o) ((o)->value.cl)
#define hvalue(o) ((o)->value.h)
#define vvalue(o) ((o)->value.v)
#define bvalue(o) ((o)->value.b)
#define l_isfalse(o) (ttype(o) == LUA_TNIL || \
@ -52,6 +52,9 @@ typedef struct lua_TObject {
#define chgnvalue(obj,x) ((obj)->value.n=(x))
#define setpvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TUDATAVAL; i_o->value.p=(x); }
#define setbvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(x); }
@ -69,9 +72,6 @@ typedef struct lua_TObject {
#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
#define setupvalue(obj,x,t) \
{ TObject *i_o=(obj); i_o->tt=(t); i_o->value.v=(x); }
#define setobj(obj1,obj2) \
{ TObject *o1=(obj1); const TObject *o2=(obj2); \
o1->tt=o2->tt; o1->value = o2->value; }
@ -106,9 +106,8 @@ typedef union Udata {
union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
struct Table *metatable;
void *value;
union Udata *next; /* chain for list of all udata */
size_t len; /* least bit reserved for gc mark */
size_t len; /* least 2 bits reserved for gc mark */
} uv;
} Udata;

View File

@ -1,5 +1,5 @@
/*
** $Id: lstring.c,v 1.72 2002/02/08 22:41:09 roberto Exp roberto $
** $Id: lstring.c,v 1.73 2002/03/20 18:37:13 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@ -89,7 +89,6 @@ Udata *luaS_newudata (lua_State *L, size_t s) {
u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
u->uv.len = s;
u->uv.metatable = hvalue(defaultmeta(L));
u->uv.value = u + 1;
/* chain it on udata list */
u->uv.next = G(L)->rootudata;
G(L)->rootudata = u;

View File

@ -1,5 +1,5 @@
/*
** $Id: ltable.c,v 1.101 2002/02/14 21:41:08 roberto Exp roberto $
** $Id: ltable.c,v 1.102 2002/03/18 18:18:35 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@ -73,7 +73,9 @@ Node *luaH_mainposition (const Table *t, const TObject *key) {
return hashstr(t, tsvalue(key));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
default: /* all other types are hashed as (void *) */
case LUA_TUDATAVAL:
return hashpointer(t, pvalue(key));
default: /* other types are hashed as (struct *) */
return hashpointer(t, tsvalue(key));
}
}

View File

@ -1,5 +1,5 @@
/*
** $Id: ltests.c,v 1.114 2002/03/25 17:47:14 roberto Exp roberto $
** $Id: ltests.c,v 1.115 2002/04/02 20:43:08 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@ -368,14 +368,14 @@ static int newuserdata (lua_State *L) {
return 1;
}
static int newuserdatabox (lua_State *L) {
lua_newuserdatabox(L, cast(void *, luaL_check_int(L, 1)));
static int pushuserdata (lua_State *L) {
lua_pushudataval(L, cast(void *, luaL_check_int(L, 1)));
return 1;
}
static int udataval (lua_State *L) {
luaL_check_type(L, 1, LUA_TUSERDATA);
lua_pushnumber(L, cast(int, lua_touserdata(L, 1)));
return 1;
}
@ -662,7 +662,7 @@ static const struct luaL_reg tests_funcs[] = {
{"s2d", s2d},
{"metatable", metatable},
{"newuserdata", newuserdata},
{"newuserdatabox", newuserdatabox},
{"pushuserdata", pushuserdata},
{"udataval", udataval},
{"doonnewstack", doonnewstack},
{"newstate", newstate},

5
ltm.c
View File

@ -1,5 +1,5 @@
/*
** $Id: ltm.c,v 1.87 2002/02/14 21:40:29 roberto Exp roberto $
** $Id: ltm.c,v 1.88 2002/03/18 20:24:14 roberto Exp roberto $
** Tag methods
** See Copyright Notice in lua.h
*/
@ -19,7 +19,8 @@
const char *const luaT_typenames[] = {
"nil", "number", "string", "boolean", "table", "userdata", "function"
"nil", "number", "string", "boolean", "table",
"userdata", "userdata", "function"
};

4
lua.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.79 2002/03/27 18:00:13 roberto Exp roberto $
** $Id: lua.c,v 1.80 2002/04/01 14:42:33 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@ -334,7 +334,7 @@ static int handle_argv (char *argv[], int *toclose) {
static void register_getargs (char *argv[]) {
lua_newuserdatabox(L, argv);
lua_pushudataval(L, argv);
lua_pushcclosure(L, l_getargs, 1);
lua_setglobal(L, "getargs");
}

16
lua.h
View File

@ -1,5 +1,5 @@
/*
** $Id: lua.h,v 1.124 2002/03/27 12:49:53 roberto Exp roberto $
** $Id: lua.h,v 1.125 2002/03/27 15:30:41 roberto Exp roberto $
** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: info@lua.org
@ -17,8 +17,8 @@
#define LUA_VERSION "Lua 4.1 (beta)"
#define LUA_COPYRIGHT "Copyright (C) 1994-2001 TeCGraf, PUC-Rio"
#define LUA_VERSION "Lua 5.0 (alpha)"
#define LUA_COPYRIGHT "Copyright (C) 1994-2002 TeCGraf, PUC-Rio"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
@ -63,7 +63,8 @@ typedef int (*lua_CFunction) (lua_State *L);
#define LUA_TBOOLEAN 3
#define LUA_TTABLE 4
#define LUA_TUSERDATA 5
#define LUA_TFUNCTION 6
#define LUA_TUDATAVAL 6
#define LUA_TFUNCTION 7
/* minimum Lua stack available to a C function */
@ -143,6 +144,7 @@ LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len);
LUA_API void lua_pushstring (lua_State *L, const char *s);
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
LUA_API void lua_pushboolean (lua_State *L, int b);
LUA_API void lua_pushudataval (lua_State *L, void *p);
/*
@ -204,7 +206,6 @@ LUA_API int lua_getn (lua_State *L, int index);
LUA_API void lua_concat (lua_State *L, int n);
LUA_API void *lua_newuserdata (lua_State *L, size_t size);
LUA_API void lua_newuserdatabox (lua_State *L, void *u);
@ -214,6 +215,11 @@ LUA_API void lua_newuserdatabox (lua_State *L, void *u);
** ===============================================================
*/
#define lua_newpointerbox(L,u) \
(*(void **)(lua_newuserdata(L, sizeof(void *))) = (u))
#define lua_getfrombox(L,i) (*(void **)(lua_touserdata(L, i)))
#define lua_pop(L,n) lua_settop(L, -(n)-1)
#define lua_register(L,n,f) \