diff --git a/hash.c b/hash.c index 90d81293..8565d4f2 100644 --- 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 index f19a1351..459f87c0 100644 --- 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 index 5c03d7b5..281cf1bb 100644 --- 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 #include @@ -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 index 1ee6bf97..dde9c11d 100644 --- 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 index 5ebdf84b..f594824f 100644 --- 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 @@ -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 index ebdad6e0..4f2212b4 100644 --- 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