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 ** Lua API
** See Copyright Notice in lua.h ** 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) { LUA_API void *lua_touserdata (lua_State *L, int index) {
StkId o = luaA_indexAcceptable(L, 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) ** get functions (Lua -> stack)
@ -472,7 +485,7 @@ LUA_API void lua_setmetatable (lua_State *L, int objindex) {
StkId obj, mt; StkId obj, mt;
lua_lock(L); lua_lock(L);
api_checknelems(L, 1); api_checknelems(L, 1);
obj = luaA_indexAcceptable(L, objindex); obj = luaA_index(L, objindex);
mt = --L->top; mt = --L->top;
if (ttype(mt) == LUA_TNIL) if (ttype(mt) == LUA_TNIL)
mt = defaultmeta(L); 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) { LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u; Udata *u;
void *p;
lua_lock(L); lua_lock(L);
u = pushnewudata(L, size); u = luaS_newudata(L, size);
p = u->uv.value; setuvalue(L->top, u);
lua_unlock(L); api_incr_top(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;
lua_unlock(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 ** Basic library
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -206,7 +206,7 @@ static int passresults (lua_State *L, int status, int oldtop) {
if (nresults > 0) if (nresults > 0)
return nresults; /* results are already on the stack */ return nresults; /* results are already on the stack */
else { 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; return 1;
} }
} }
@ -383,6 +383,7 @@ static int luaB_tostring (lua_State *L) {
sprintf(buff, "function: %p", lua_topointer(L, 1)); sprintf(buff, "function: %p", lua_topointer(L, 1));
break; break;
case LUA_TUSERDATA: case LUA_TUSERDATA:
case LUA_TUDATAVAL:
sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
break; break;
case LUA_TNIL: case LUA_TNIL:
@ -439,7 +440,7 @@ static void base_open (lua_State *L) {
static int luaB_resume (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) if (lua_resume(L, co) != 0)
lua_error(L, "error running co-routine"); lua_error(L, "error running co-routine");
return lua_gettop(L); return lua_gettop(L);
@ -448,7 +449,7 @@ static int luaB_resume (lua_State *L) {
static int gc_coroutine (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); lua_closethread(L, co);
return 0; return 0;
} }
@ -471,7 +472,7 @@ static int luaB_coroutine (lua_State *L) {
lua_unref(L, ref); lua_unref(L, ref);
} }
lua_cobegin(NL, n-1); lua_cobegin(NL, n-1);
lua_newuserdatabox(L, NL); lua_newpointerbox(L, NL);
lua_pushliteral(L, "Coroutine"); lua_pushliteral(L, "Coroutine");
lua_rawget(L, LUA_REGISTRYINDEX); lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2); 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 ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -46,7 +46,8 @@ typedef struct GCState {
#define ismarkable(o) (!((1 << ttype(o)) & \ #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); 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 ** Standard I/O (and system) library
** See Copyright Notice in lua.h ** 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) { 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) && if (f && lua_getmetatable(L, findex) &&
lua_equal(L, -1, lua_upvalueindex(1))) { lua_equal(L, -1, lua_upvalueindex(1))) {
lua_pop(L, 1); lua_pop(L, 1);
return f; return *f;
} }
luaL_argerror(L, findex, "bad file"); luaL_argerror(L, findex, "bad file");
return NULL; /* to avoid warnings */ 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) { static void newfile (lua_State *L, FILE *f) {
lua_newuserdatabox(L, f); lua_newpointerbox(L, f);
lua_pushliteral(L, FILEHANDLE); lua_pushliteral(L, FILEHANDLE);
lua_rawget(L, LUA_REGISTRYINDEX); lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2); 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 ** Some generic functions over Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -59,7 +59,9 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
return 1; return 1;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ 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); 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 ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -13,15 +13,15 @@
/* tags for values visible from Lua */ /* tags for values visible from Lua */
#define NUM_TAGS 6 #define NUM_TAGS LUA_TFUNCTION
typedef union { typedef union {
void *p;
union TString *ts; union TString *ts;
union Udata *u; union Udata *u;
union Closure *cl; union Closure *cl;
struct Table *h; struct Table *h;
struct lua_TObject *v;
lua_Number n; lua_Number n;
int b; int b;
} Value; } Value;
@ -35,12 +35,12 @@ typedef struct lua_TObject {
/* Macros to access values */ /* Macros to access values */
#define ttype(o) ((o)->tt) #define ttype(o) ((o)->tt)
#define pvalue(o) ((o)->value.p)
#define nvalue(o) ((o)->value.n) #define nvalue(o) ((o)->value.n)
#define tsvalue(o) ((o)->value.ts) #define tsvalue(o) ((o)->value.ts)
#define uvalue(o) ((o)->value.u) #define uvalue(o) ((o)->value.u)
#define clvalue(o) ((o)->value.cl) #define clvalue(o) ((o)->value.cl)
#define hvalue(o) ((o)->value.h) #define hvalue(o) ((o)->value.h)
#define vvalue(o) ((o)->value.v)
#define bvalue(o) ((o)->value.b) #define bvalue(o) ((o)->value.b)
#define l_isfalse(o) (ttype(o) == LUA_TNIL || \ #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 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) \ #define setbvalue(obj,x) \
{ TObject *i_o=(obj); i_o->tt=LUA_TBOOLEAN; i_o->value.b=(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 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) \ #define setobj(obj1,obj2) \
{ TObject *o1=(obj1); const TObject *o2=(obj2); \ { TObject *o1=(obj1); const TObject *o2=(obj2); \
o1->tt=o2->tt; o1->value = o2->value; } 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 */ union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct { struct {
struct Table *metatable; struct Table *metatable;
void *value;
union Udata *next; /* chain for list of all udata */ 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; } uv;
} Udata; } 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) ** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h ** 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 = cast(Udata *, luaM_malloc(L, sizeudata(s)));
u->uv.len = s; u->uv.len = s;
u->uv.metatable = hvalue(defaultmeta(L)); u->uv.metatable = hvalue(defaultmeta(L));
u->uv.value = u + 1;
/* chain it on udata list */ /* chain it on udata list */
u->uv.next = G(L)->rootudata; u->uv.next = G(L)->rootudata;
G(L)->rootudata = u; 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) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -73,7 +73,9 @@ Node *luaH_mainposition (const Table *t, const TObject *key) {
return hashstr(t, tsvalue(key)); return hashstr(t, tsvalue(key));
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key)); 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)); 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 ** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -368,14 +368,14 @@ static int newuserdata (lua_State *L) {
return 1; 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; return 1;
} }
static int udataval (lua_State *L) { static int udataval (lua_State *L) {
luaL_check_type(L, 1, LUA_TUSERDATA);
lua_pushnumber(L, cast(int, lua_touserdata(L, 1))); lua_pushnumber(L, cast(int, lua_touserdata(L, 1)));
return 1; return 1;
} }
@ -662,7 +662,7 @@ static const struct luaL_reg tests_funcs[] = {
{"s2d", s2d}, {"s2d", s2d},
{"metatable", metatable}, {"metatable", metatable},
{"newuserdata", newuserdata}, {"newuserdata", newuserdata},
{"newuserdatabox", newuserdatabox}, {"pushuserdata", pushuserdata},
{"udataval", udataval}, {"udataval", udataval},
{"doonnewstack", doonnewstack}, {"doonnewstack", doonnewstack},
{"newstate", newstate}, {"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 ** Tag methods
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -19,7 +19,8 @@
const char *const luaT_typenames[] = { 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 ** Lua stand-alone interpreter
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -334,7 +334,7 @@ static int handle_argv (char *argv[], int *toclose) {
static void register_getargs (char *argv[]) { static void register_getargs (char *argv[]) {
lua_newuserdatabox(L, argv); lua_pushudataval(L, argv);
lua_pushcclosure(L, l_getargs, 1); lua_pushcclosure(L, l_getargs, 1);
lua_setglobal(L, "getargs"); 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 ** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: info@lua.org ** e-mail: info@lua.org
@ -17,8 +17,8 @@
#define LUA_VERSION "Lua 4.1 (beta)" #define LUA_VERSION "Lua 5.0 (alpha)"
#define LUA_COPYRIGHT "Copyright (C) 1994-2001 TeCGraf, PUC-Rio" #define LUA_COPYRIGHT "Copyright (C) 1994-2002 TeCGraf, PUC-Rio"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" #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_TBOOLEAN 3
#define LUA_TTABLE 4 #define LUA_TTABLE 4
#define LUA_TUSERDATA 5 #define LUA_TUSERDATA 5
#define LUA_TFUNCTION 6 #define LUA_TUDATAVAL 6
#define LUA_TFUNCTION 7
/* minimum Lua stack available to a C function */ /* 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_pushstring (lua_State *L, const char *s);
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); 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_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_concat (lua_State *L, int n);
LUA_API void *lua_newuserdata (lua_State *L, size_t size); 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_pop(L,n) lua_settop(L, -(n)-1)
#define lua_register(L,n,f) \ #define lua_register(L,n,f) \