new API function `createuserdata'
This commit is contained in:
13
lapi.c
13
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;
|
||||
}
|
||||
|
||||
|
||||
6
lgc.c
6
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--;
|
||||
}
|
||||
}
|
||||
|
||||
30
liolib.c
30
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; i<sizeof(iolibtag)/sizeof(iolibtag[0]); i++) {
|
||||
/* put `ctrl' as upvalue for these functions */
|
||||
lua_pushusertag(L, ctrl, ctrltag);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushcclosure(L, iolibtag[i].func, 1);
|
||||
lua_setglobal(L, iolibtag[i].name);
|
||||
}
|
||||
@@ -712,12 +702,10 @@ static void openwithcontrol (lua_State *L) {
|
||||
setfilebyname(L, ctrl, stdin, "_STDIN");
|
||||
setfilebyname(L, ctrl, stdout, "_STDOUT");
|
||||
setfilebyname(L, ctrl, stderr, "_STDERR");
|
||||
/* delete `ctrl' when collected */
|
||||
lua_pushusertag(L, ctrl, ctrltag);
|
||||
lua_pushcclosure(L, file_collect, 1);
|
||||
lua_settagmethod(L, ctrltag, "gc");
|
||||
/* close files when collected */
|
||||
lua_copytagmethods(L, ctrl->iotag, 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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
10
lmathlib.c
10
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");
|
||||
}
|
||||
|
||||
|
||||
5
lmem.c
5
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) */
|
||||
|
||||
@@ -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! */
|
||||
|
||||
3
lstate.c
3
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");
|
||||
|
||||
35
lstring.c
35
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
4
ltable.c
4
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' */
|
||||
|
||||
7
ltests.c
7
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;
|
||||
}
|
||||
|
||||
|
||||
4
lua.h
4
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);
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
|
||||
16
lvm.c
16
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user