userdata can handle arbitrary binary data;

user tag is stored with data;
This commit is contained in:
Roberto Ierusalimschy 1997-02-11 09:40:01 -02:00
parent b48847c5fa
commit 205ee1ec84
6 changed files with 79 additions and 41 deletions

18
hash.c
View File

@ -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 */
}
}

7
lua.h
View File

@ -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);

View File

@ -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));
}
}

View File

@ -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)

38
tree.c
View File

@ -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);
}

7
tree.h
View File

@ -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