commit 205ee1ec84c0f0e9c2df923fdcfa29207e8e72b3
parent b48847c5fac055f0d6120029f6fe1a50c852a8ac
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Tue, 11 Feb 1997 09:39:41 -0200
userdata can handle arbitrary binary data;
user tag is stored with data;
Diffstat:
M | hash.c | | | 18 | +++++++++--------- |
M | lua.h | | | 7 | +++++-- |
M | opcode.c | | | 46 | ++++++++++++++++++++++++++++++++++++---------- |
M | opcode.h | | | 4 | +--- |
M | tree.c | | | 38 | +++++++++++++++++++++++--------------- |
M | tree.h | | | 7 | +++++-- |
6 files changed, 79 insertions(+), 41 deletions(-)
diff --git a/hash.c b/hash.c
@@ -3,7 +3,7 @@
** hash manager for lua
*/
-char *rcs_hash="$Id: hash.c,v 2.31 1996/07/12 20:00:26 roberto Exp roberto $";
+char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp roberto $";
#include "mem.h"
@@ -50,12 +50,9 @@ static int hashindex (Hash *t, Object *ref) /* hash function */
{
long int h;
switch (tag(ref)) {
- case LUA_T_NIL:
- lua_error ("unexpected type to index table");
- h = 0; /* UNREACHEABLE */
case LUA_T_NUMBER:
h = (long int)nvalue(ref); break;
- case LUA_T_STRING:
+ case LUA_T_STRING: case LUA_T_USERDATA:
h = tsvalue(ref)->hash; break;
case LUA_T_FUNCTION:
h = (IntPoint)ref->value.tf; break;
@@ -63,8 +60,9 @@ static int hashindex (Hash *t, Object *ref) /* hash function */
h = (IntPoint)fvalue(ref); break;
case LUA_T_ARRAY:
h = (IntPoint)avalue(ref); break;
- default: /* user data */
- h = (IntPoint)uvalue(ref); break;
+ default:
+ lua_error ("unexpected type to index table");
+ h = 0; /* UNREACHEABLE */
}
if (h < 0) h = -h;
return h%nhash(t); /* make it a valid index */
@@ -77,11 +75,13 @@ int lua_equalObj (Object *t1, Object *t2)
{
case LUA_T_NIL: return 1;
case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2);
- case LUA_T_STRING: return svalue(t1) == svalue(t2);
+ case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2);
case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf;
case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2);
- default: return uvalue(t1) == uvalue(t2);
+ default:
+ lua_error("internal error at `lua_equalObj'");
+ return 0; /* UNREACHEABLE */
}
}
diff --git a/lua.h b/lua.h
@@ -2,14 +2,14 @@
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
-** $Id: lua.h,v 3.31 1996/11/12 16:00:16 roberto Exp roberto $
+** $Id: lua.h,v 3.32 1996/11/20 13:49:32 roberto Exp roberto $
*/
#ifndef lua_h
#define lua_h
-#define LUA_VERSION "Lua 2.5.1"
+#define LUA_VERSION "Lua 2.?"
#define LUA_COPYRIGHT "Copyright (C) 1994-1996 TeCGraf"
#define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo"
@@ -63,12 +63,15 @@ int lua_isfunction (lua_Object object);
float lua_getnumber (lua_Object object);
char *lua_getstring (lua_Object object);
lua_CFunction lua_getcfunction (lua_Object object);
+void *lua_getbinarydata (lua_Object object);
+int lua_getbindatasize (lua_Object object);
void *lua_getuserdata (lua_Object object);
void lua_pushnil (void);
void lua_pushnumber (float n);
void lua_pushstring (char *s);
void lua_pushcfunction (lua_CFunction fn);
+void lua_pushbinarydata (void *buff, int size, int tag);
void lua_pushusertag (void *u, int tag);
void lua_pushobject (lua_Object object);
diff --git a/opcode.c b/opcode.c
@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_opcode="$Id: opcode.c,v 3.78 1996/11/22 13:08:28 roberto Exp roberto $";
+char *rcs_opcode="$Id: opcode.c,v 3.79 1997/01/31 14:27:11 roberto Exp roberto $";
#include <setjmp.h>
#include <stdio.h>
@@ -709,6 +709,20 @@ char *lua_getstring (lua_Object object)
else return (svalue(Address(object)));
}
+void *lua_getbinarydata (lua_Object object)
+{
+ if (object == LUA_NOOBJECT || tag(Address(object)) != LUA_T_USERDATA)
+ lua_error("getbinarydata: object is not binary data");
+ return svalue(Address(object));
+}
+
+int lua_getbindatasize (lua_Object object)
+{
+ if (object == LUA_NOOBJECT || tag(Address(object)) != LUA_T_USERDATA)
+ return 0;
+ else return (Address(object))->value.ts->size;
+}
+
/*
** Given an object handle, return its cfuntion pointer. On error, return NULL.
*/
@@ -725,9 +739,7 @@ lua_CFunction lua_getcfunction (lua_Object object)
*/
void *lua_getuserdata (lua_Object object)
{
- if (object == LUA_NOOBJECT || tag(Address(object)) < LUA_T_USERDATA)
- return NULL;
- else return (uvalue(Address(object)));
+ return *(void **)lua_getbinarydata(object);
}
@@ -825,15 +837,25 @@ void lua_pushcfunction (lua_CFunction fn)
incr_top;
}
+void lua_pushbinarydata (void *buff, int size, int tag)
+{
+ if (buff == NULL)
+ tag(top) = LUA_T_NIL;
+ else {
+ tsvalue(top) = luaI_createuserdata(buff, size, tag);
+ tag(top) = LUA_T_USERDATA;
+ }
+ incr_top;
+}
+
/*
** Push an object (tag=userdata) to stack.
*/
void lua_pushusertag (void *u, int tag)
{
- if (tag < LUA_T_USERDATA)
- lua_error("invalid tag in `lua_pushusertag'");
- tag(top) = tag; uvalue(top) = u;
- incr_top;
+ if (tag < LUA_T_USERDATA)
+ lua_error("invalid tag in `lua_pushusertag'");
+ lua_pushbinarydata(&u, sizeof(void *), tag);
}
/*
@@ -862,8 +884,12 @@ int lua_type (lua_Object o)
{
if (o == LUA_NOOBJECT)
return LUA_T_NIL;
- else
- return tag(Address(o));
+ else {
+ lua_Type t = tag(Address(o));
+ if (t == LUA_T_USERDATA)
+ return (Address(o))->value.ts->tag;
+ else return tag(Address(o));
+ }
}
diff --git a/opcode.h b/opcode.h
@@ -1,6 +1,6 @@
/*
** TeCGraf - PUC-Rio
-** $Id: opcode.h,v 3.23 1996/09/26 21:08:41 roberto Exp roberto $
+** $Id: opcode.h,v 3.24 1996/11/01 12:46:59 roberto Exp roberto $
*/
#ifndef opcode_h
@@ -102,7 +102,6 @@ typedef union
TaggedString *ts;
TFunc *tf;
struct Hash *a;
- void *u;
int i;
} Value;
@@ -120,7 +119,6 @@ typedef struct Object
#define tsvalue(o) ((o)->value.ts)
#define avalue(o) ((o)->value.a)
#define fvalue(o) ((o)->value.f)
-#define uvalue(o) ((o)->value.u)
/* Macros to access symbol table */
#define s_object(i) (lua_table[i].object)
diff --git a/tree.c b/tree.c
@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_tree="$Id: tree.c,v 1.19 1996/02/22 20:34:33 roberto Exp $";
+char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $";
#include <string.h>
@@ -28,14 +28,14 @@ static int initialized = 0;
static stringtable string_root[NUM_HASHS];
-static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}};
+static TaggedString EMPTY = {LUA_T_STRING, 0, NOT_USED, NOT_USED, 0, 2, {0}};
-static unsigned long hash (char *str)
+static unsigned long hash (char *buff, long size)
{
unsigned long h = 0;
- while (*str)
- h = ((h<<5)-h)^(unsigned char)*(str++);
+ while (size--)
+ h = ((h<<5)-h)^(unsigned char)*(buff++);
return h;
}
@@ -71,10 +71,10 @@ static void grow (stringtable *tb)
tb->hash = newhash;
}
-static TaggedString *insert (char *str, stringtable *tb)
+static TaggedString *insert (char *buff, long size, int tag, stringtable *tb)
{
TaggedString *ts;
- unsigned long h = hash(str);
+ unsigned long h = hash(buff, size);
int i;
int j = -1;
if ((Long)tb->nuse*3 >= (Long)tb->size*2)
@@ -84,12 +84,13 @@ static TaggedString *insert (char *str, stringtable *tb)
grow(tb);
}
i = h%tb->size;
- while (tb->hash[i])
+ while ((ts = tb->hash[i]) != NULL)
{
- if (tb->hash[i] == &EMPTY)
+ if (ts == &EMPTY)
j = i;
- else if (strcmp(str, tb->hash[i]->str) == 0)
- return tb->hash[i];
+ else if (ts->size == size && ts->tag == tag &&
+ memcmp(buff, ts->str, size) == 0)
+ return ts;
i = (i+1)%tb->size;
}
/* not found */
@@ -98,17 +99,24 @@ static TaggedString *insert (char *str, stringtable *tb)
i = j;
else
tb->nuse++;
- ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str));
- strcpy(ts->str, str);
+ ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+size-1);
+ memcpy(ts->str, buff, size);
+ ts->tag = tag;
+ ts->size = size;
ts->marked = 0;
ts->hash = h;
ts->varindex = ts->constindex = NOT_USED;
return ts;
}
-TaggedString *lua_createstring (char *str)
+TaggedString *luaI_createuserdata (char *buff, long size, int tag)
{
- return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]);
+ return insert(buff, size, tag, &string_root[(unsigned)buff[0]%NUM_HASHS]);
+}
+
+TaggedString *lua_createstring (char *str)
+{
+ return luaI_createuserdata(str, strlen(str)+1, LUA_T_STRING);
}
diff --git a/tree.h b/tree.h
@@ -1,7 +1,7 @@
/*
** tree.h
** TecCGraf - PUC-Rio
-** $Id: tree.h,v 1.13 1996/02/14 13:35:51 roberto Exp roberto $
+** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp roberto $
*/
#ifndef tree_h
@@ -14,15 +14,18 @@
typedef struct TaggedString
{
+ int tag; /* if != LUA_T_STRING, this is a userdata */
+ long size;
Word varindex; /* != NOT_USED if this is a symbol */
Word constindex; /* != NOT_USED if this is a constant */
unsigned long hash; /* 0 if not initialized */
int marked; /* for garbage collection; never collect (nor change) if > 1 */
- char str[1]; /* \0 byte already reserved */
+ char str[1]; /* \0 byte already reserved; MAY BE NOT 0 TERMINATED!! */
} TaggedString;
TaggedString *lua_createstring (char *str);
+TaggedString *luaI_createuserdata (char *buff, long size, int tag);
Long lua_strcollector (void);
#endif