From b892f0a8774f573d7ec9b02617428871b8d3a2b3 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 26 Oct 2000 10:47:05 -0200 Subject: new API function `createuserdata' --- lapi.c | 13 +++++++++++-- lgc.c | 6 +++--- liolib.c | 30 +++++++++--------------------- llimits.h | 7 ++++++- lmathlib.c | 10 +++++----- lmem.c | 5 ++--- lobject.h | 5 +++-- lstate.c | 3 ++- lstring.c | 35 ++++++++++++++++++++++------------- lstring.h | 4 ++-- ltable.c | 4 ++-- ltests.c | 7 +++++-- lua.h | 4 +++- lvm.c | 16 ++++++++-------- 14 files changed, 83 insertions(+), 66 deletions(-) diff --git a/lapi.c b/lapi.c index f0c64191..adcd0ef1 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.107 2000/10/20 16:39:03 roberto Exp roberto $ +** $Id: lapi.c,v 1.108 2000/10/24 19:19:15 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -173,7 +173,7 @@ LUA_API const char *lua_tostring (lua_State *L, int index) { LUA_API size_t lua_strlen (lua_State *L, int index) { StkId o = luaA_indexAcceptable(L, index); if (o == NULL || tostring(L, o)) return 0; - else return tsvalue(o)->u.s.len; + else return tsvalue(o)->len; } LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) { @@ -491,3 +491,12 @@ LUA_API void lua_concat (lua_State *L, int n) { luaC_checkGC(L); } + +LUA_API void *lua_newuserdata (lua_State *L, size_t size) { + TString *ts = luaS_newudata(L, size, NULL); + tsvalue(L->top) = ts; + ttype(L->top) = LUA_TUSERDATA; + api_incr_top(L); + return ts->u.d.value; +} + diff --git a/lgc.c b/lgc.c index 02ca2794..3ffc331d 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.70 2000/10/05 12:14:08 roberto Exp roberto $ +** $Id: lgc.c,v 1.71 2000/10/05 13:00:17 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -248,7 +248,7 @@ static void collectstrings (lua_State *L, int all) { else { /* collect */ *p = next->nexthash; L->strt.nuse--; - L->nblocks -= sizestring(next->u.s.len); + L->nblocks -= sizestring(next->len); luaM_free(L, next); } } @@ -273,7 +273,7 @@ static void collectudata (lua_State *L, int all) { *p = next->nexthash; next->nexthash = L->TMtable[tag].collected; /* chain udata */ L->TMtable[tag].collected = next; - L->nblocks -= gcsizeudata; + L->nblocks -= sizestring(next->len); L->udt.nuse--; } } diff --git a/liolib.c b/liolib.c index 0e58a942..b1fddebe 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 1.86 2000/10/02 20:10:55 roberto Exp roberto $ +** $Id: liolib.c,v 1.87 2000/10/20 16:39:03 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -159,18 +159,9 @@ static int io_close (lua_State *L) { static int file_collect (lua_State *L) { IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, -1); - lua_pop(L, 1); /* remove upvalue */ - if (ctrl == (IOCtrl *)lua_touserdata(L, 1)) { - /* collecting `ctrl' itself */ - lua_unref(L, ctrl->ref[INFILE]); - lua_unref(L, ctrl->ref[OUTFILE]); - free(ctrl); - } - else { /* collecting a file: Close it */ - FILE *f = getnonullfile(L, ctrl, 1); - if (f != stdin && f != stdout && f != stderr) - CLOSEFILE(L, f); - } + FILE *f = getnonullfile(L, ctrl, 1); + if (f != stdin && f != stdout && f != stderr) + CLOSEFILE(L, f); return 0; } @@ -690,14 +681,13 @@ static const struct luaL_reg iolibtag[] = { static void openwithcontrol (lua_State *L) { - IOCtrl *ctrl = (IOCtrl *)malloc(sizeof(IOCtrl)); + IOCtrl *ctrl = (IOCtrl *)lua_newuserdata(L, sizeof(IOCtrl)); unsigned int i; - int ctrltag = lua_newtag(L); ctrl->iotag = lua_newtag(L); ctrl->closedtag = lua_newtag(L); for (i=0; iiotag, ctrltag); + lua_pushcclosure(L, file_collect, 1); /* pops `ctrl' from stack */ + lua_settagmethod(L, ctrl->iotag, "gc"); + lua_pop(L, 1); /* remove tag method returned by previous call */ } diff --git a/llimits.h b/llimits.h index 8c0c1b48..ca1619ba 100644 --- a/llimits.h +++ b/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.17 2000/10/06 19:28:38 roberto Exp roberto $ +** $Id: llimits.h,v 1.18 2000/10/09 13:47:32 roberto Exp roberto $ ** Limits, basic types, and some other "installation-dependent" definitions ** See Copyright Notice in lua.h */ @@ -76,6 +76,11 @@ typedef unsigned long lint32; /* unsigned int with at least 32 bits */ +/* type to ensure maximum alignment */ +union L_Umaxalign { double d; char *s; long l; }; + + + /* ** type for virtual-machine instructions ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) diff --git a/lmathlib.c b/lmathlib.c index 67ef899a..6551564a 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.28 2000/08/31 20:23:40 roberto Exp roberto $ +** $Id: lmathlib.c,v 1.29 2000/10/20 16:39:03 roberto Exp roberto $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -230,10 +230,10 @@ static const struct luaL_reg mathlib[] = { */ LUA_API void lua_mathlibopen (lua_State *L) { luaL_openl(L, mathlib); - lua_pushnumber(L, 0); /* to get its tag */ lua_pushcfunction(L, math_pow); - lua_settagmethod(L, lua_tag(L, -2), "pow"); - lua_pop(L, 1); /* remove number */ - lua_pushnumber(L, PI); lua_setglobal(L, "PI"); + lua_settagmethod(L, LUA_TNUMBER, "pow"); + lua_pop(L, 1); /* remove result from previous call */ + lua_pushnumber(L, PI); + lua_setglobal(L, "PI"); } diff --git a/lmem.c b/lmem.c index bd6b58da..7bcc1a35 100644 --- a/lmem.c +++ b/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.36 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lmem.c,v 1.37 2000/10/11 16:47:50 roberto Exp roberto $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -35,8 +35,7 @@ /* ensures maximum alignment for HEADER */ -union L_U { double d; char *s; long l; }; -#define HEADER (sizeof(union L_U)) +#define HEADER (sizeof(union L_Umaxalign)) #define MARKSIZE 16 #define MARK 0x55 /* 01010101 (a nice pattern) */ diff --git a/lobject.h b/lobject.h index dd7adeda..a3638622 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.78 2000/10/02 20:10:55 roberto Exp roberto $ +** $Id: lobject.h,v 1.79 2000/10/05 12:14:08 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -73,9 +73,9 @@ typedef struct lua_TObject { */ typedef struct TString { union { + union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ struct { /* for strings */ unsigned long hash; - size_t len; int constindex; /* hint to reuse constants */ } s; struct { /* for userdata */ @@ -83,6 +83,7 @@ typedef struct TString { void *value; } d; } u; + size_t len; struct TString *nexthash; /* chain for hash table */ unsigned char marked; char str[1]; /* variable length string!! must be the last field! */ diff --git a/lstate.c b/lstate.c index ba7ed328..4593e5eb 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.45 2000/10/20 16:39:03 roberto Exp roberto $ +** $Id: lstate.c,v 1.46 2000/10/24 19:12:06 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -98,6 +98,7 @@ LUA_API lua_State *lua_open (int stacksize) { LUA_API void lua_close (lua_State *L) { + LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack"); luaC_collect(L, 1); /* collect all elements */ LUA_ASSERT(L->rootproto == NULL, "list should be empty"); LUA_ASSERT(L->rootcl == NULL, "list should be empty"); diff --git a/lstring.c b/lstring.c index 02dd54c1..7990248c 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 1.42 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lstring.c,v 1.43 2000/09/29 12:42:13 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -81,17 +81,17 @@ static void newentry (lua_State *L, stringtable *tb, TString *ts, int h) { TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { unsigned long h = hash_s(str, l); - int h1 = h&(L->strt.size-1); + int h1 = h & (L->strt.size-1); TString *ts; for (ts = L->strt.hash[h1]; ts; ts = ts->nexthash) { - if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) + if (ts->len == l && (memcmp(str, ts->str, l) == 0)) return ts; } /* not found */ ts = (TString *)luaM_malloc(L, sizestring(l)); ts->marked = 0; ts->nexthash = NULL; - ts->u.s.len = l; + ts->len = l; ts->u.s.hash = h; ts->u.s.constindex = 0; memcpy(ts->str, str, l); @@ -102,22 +102,31 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { } +TString *luaS_newudata (lua_State *L, size_t s, void *udata) { + TString *ts = (TString *)luaM_malloc(L, (lint32)sizeof(TString)+s); + ts->marked = 0; + ts->nexthash = NULL; + ts->len = s; + ts->u.d.tag = 0; + ts->u.d.value = (udata == NULL) ? ts+1 : udata; + L->nblocks += sizestring(s); + /* insert it on table */ + newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1)); + return ts; +} + + TString *luaS_createudata (lua_State *L, void *udata, int tag) { - unsigned long h = IntPoint(udata); - int h1 = h&(L->udt.size-1); + int h1 = IntPoint(udata) & (L->udt.size-1); TString *ts; for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) { if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG)) return ts; } /* not found */ - ts = luaM_new(L, TString); - ts->marked = 0; - ts->nexthash = NULL; - ts->u.d.value = udata; - ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; - L->nblocks += gcsizeudata; - newentry(L, &L->udt, ts, h1); /* insert it on table */ + ts = luaS_newudata(L, 0, udata); + if (tag != LUA_ANYTAG) + ts->u.d.tag = tag; return ts; } diff --git a/lstring.h b/lstring.h index c04ef12a..aa0157b5 100644 --- a/lstring.h +++ b/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.21 2000/05/24 13:54:49 roberto Exp roberto $ +** $Id: lstring.h,v 1.22 2000/09/29 12:42:13 roberto Exp roberto $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -21,11 +21,11 @@ #define sizestring(l) (sizeof(TString)+(lint32)(l)*sizeof(char)) -#define gcsizeudata (sizeof(TString)) void luaS_init (lua_State *L); void luaS_resize (lua_State *L, stringtable *tb, int newsize); +TString *luaS_newudata (lua_State *L, size_t s, void *udata); TString *luaS_createudata (lua_State *L, void *udata, int tag); void luaS_freeall (lua_State *L); TString *luaS_newlstr (lua_State *L, const char *str, size_t l); diff --git a/ltable.c b/ltable.c index 0e0fe772..4aef89c0 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.56 2000/09/29 12:42:13 roberto Exp roberto $ +** $Id: ltable.c,v 1.57 2000/10/05 12:14:08 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -139,7 +139,7 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) { */ void luaH_remove (Hash *t, TObject *key) { if (ttype(key) == LUA_TNUMBER || - (ttype(key) == LUA_TSTRING && tsvalue(key)->u.s.len <= 30)) + (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30)) return; /* do not remove numbers nor small strings */ else { /* try to find a number `n' with the same hash as `key' */ diff --git a/ltests.c b/ltests.c index 8470ab19..111c9f64 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.50 2000/10/06 19:29:26 roberto Exp roberto $ +** $Id: ltests.c,v 1.51 2000/10/20 16:39:03 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -260,7 +260,10 @@ static int unref (lua_State *L) { } static int newuserdata (lua_State *L) { - lua_pushusertag(L, (void *)luaL_check_int(L, 1), luaL_check_int(L, 2)); + if (lua_isnumber(L, 2)) + lua_pushusertag(L, (void *)luaL_check_int(L, 1), luaL_check_int(L, 2)); + else + lua_newuserdata(L, luaL_check_int(L, 1)); return 1; } diff --git a/lua.h b/lua.h index c2c77a80..599dfafd 100644 --- a/lua.h +++ b/lua.h @@ -1,5 +1,5 @@ /* -** $Id: lua.h,v 1.75 2000/10/20 16:39:03 roberto Exp roberto $ +** $Id: lua.h,v 1.76 2000/10/24 19:12:06 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 @@ -182,6 +182,8 @@ 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); + /* ** =============================================================== diff --git a/lvm.c b/lvm.c index 356dc4a1..71741cb5 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.144 2000/10/05 13:00:17 roberto Exp roberto $ +** $Id: lvm.c,v 1.145 2000/10/06 12:45:25 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -249,9 +249,9 @@ static void call_arith (lua_State *L, StkId top, TMS event) { static int luaV_strcomp (const TString *ls, const TString *rs) { const char *l = ls->str; - size_t ll = ls->u.s.len; + size_t ll = ls->len; const char *r = rs->str; - size_t lr = rs->u.s.len; + size_t lr = rs->len; for (;;) { int temp = strcoll(l, r); if (temp != 0) return temp; @@ -293,21 +293,21 @@ void luaV_strconc (lua_State *L, int total, StkId top) { if (!call_binTM(L, top, TM_CONCAT)) luaG_binerror(L, top-2, LUA_TSTRING, "concat"); } - else if (tsvalue(top-1)->u.s.len > 0) { /* if len=0, do nothing */ + else if (tsvalue(top-1)->len > 0) { /* if len=0, do nothing */ /* at least two string values; get as many as possible */ - lint32 tl = (lint32)tsvalue(top-1)->u.s.len + - (lint32)tsvalue(top-2)->u.s.len; + lint32 tl = (lint32)tsvalue(top-1)->len + + (lint32)tsvalue(top-2)->len; char *buffer; int i; while (n < total && !tostring(L, top-n-1)) { /* collect total length */ - tl += tsvalue(top-n-1)->u.s.len; + tl += tsvalue(top-n-1)->len; n++; } if (tl > MAX_SIZET) lua_error(L, "string size overflow"); buffer = luaO_openspace(L, tl); tl = 0; for (i=n; i>0; i--) { /* concat all strings */ - size_t l = tsvalue(top-i)->u.s.len; + size_t l = tsvalue(top-i)->len; memcpy(buffer+tl, tsvalue(top-i)->str, l); tl += l; } -- cgit v1.2.3-55-g6feb