Browse Source

userdata can handle arbitrary binary data;
user tag is stored with data;

Roberto Ierusalimschy 28 years ago
parent
commit
205ee1ec84
6 changed files with 79 additions and 41 deletions
  1. 9 9
      hash.c
  2. 5 2
      lua.h
  3. 36 10
      opcode.c
  4. 1 3
      opcode.h
  5. 23 15
      tree.c
  6. 5 2
      tree.h

+ 9 - 9
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 */
   }
 }
 

+ 5 - 2
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);
 

+ 36 - 10
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));
+  }
 }
 
 

+ 1 - 3
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)

+ 23 - 15
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);
 }
 
 

+ 5 - 2
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